0

I want to write and print some strings in a 2d array in a struct. The struct is called Router and it is in a header file, the 2d array is defined in that struct and it's called **addTab. When I try to print one line of the array using the function viewTable the program stopped working... why?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "router.h"
#define N 8
#define M 3
#define sizeMess 5

Router *createRouter(){
    Router *NewRouter=(Router*)malloc(sizeof(Router));
    int i;
    NewRouter->addTab=(char **) malloc(N*sizeof(char *));
    for(i=0;i<N;i++)
        NewRouter->addTab[i]=(char *) malloc(M*sizeof(char));
    return NewRouter;
}


void viewTable(Router *r, int a){
    int i,j;
    for(i=0;i<N;i++){
        for(j=0;j<M;j++){
            printf("raw\t col\t address\t value\t\n");
            printf("%d\t %d\t",i,j);
            printf("%p\t",&r->addTab[i][j]);
            printf("%s\t\n",r->addTab[i][j]);
        }
    }
}
void updateTable(Router *r, int conn, char *addr1, char *addr2){
    r->addTab[conn][1]=addr1;
    r->addTab[conn][2]=addr2;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
jack
  • 3
  • 2

3 Answers3

2

First off: Don't cast the result of malloc.

Assuming that you want to store char* pointers in your 2D array (as the title of your question says), you will need to define it as char *** in your Router structure, like this:

typedef struct router {
    char ***addTab;
} Router;

Next, you will need to change your createRouter function, so that it can store an array of char* pointers, instead of a single byte for each element, like so:

Router *createRouter(){
    Router *NewRouter=malloc(sizeof(Router));
    int i;
    NewRouter->addTab=malloc(N*sizeof(char **));
    for (i=0;i<N;i++)
        NewRouter->addTab[i]=malloc(M*sizeof(char *));
    return NewRouter;
}

I'm not sure how you call your updateTable function, but unless you actually fill up the entire array with char* pointers, your viewTable function will also invoke Undefined Behavior, because the printf statements will attempt to access uninitialized data. You could avoid this by using calloc instead of malloc when allocating the 2D array (or explicitly memset it), and then adding NULL checks in your viewTable function.

Finally, if you're calling updateTable with char* pointers that are not string literals or they have not been allocated on the heap, you might have further issues...

Community
  • 1
  • 1
Badministrator
  • 173
  • 1
  • 9
  • thanks a lot! I know i shuold avoid this but thank you very much. i use calloc for the 2d(3d?) array and it works perfectly. grazie!!! – jack Dec 28 '15 at 23:07
  • No problem. :) FWIW, it's still a 2D array, but of pointers, instead of single bytes (which is what you had before). – Badministrator Dec 28 '15 at 23:12
0

Your updateTable() doesn't work as you'd expect. You allocated memory in r->addTab[i][j] and, afterwards, assign a pointer to it (r->addTab[conn][1]=addr1). On access in viewTable, the program tries to read the memory at addr1, but most likely won't be able to read it, thus crashes.

Use a function to copy a given string to r->addTab, e.g. like so:

void router_tab_printf(Router *r, const int conn, const int i, const char *value) {
    sprintf(r->addTab[conn][i], "%s", value);
}    

This assumes that r->addTab[conn][i] is large enough to hold value.

Jeremy
  • 566
  • 1
  • 6
  • 25
  • still doesn't work.. i have this warning "passing argument 1 of 'sprintf' makes pointer from integer without a cast". – jack Dec 28 '15 at 22:40
0

you need to change your updateTable

void updateTable(Router *r, int conn, char *addr1, char *addr2){
strcpy(r->addTab[conn], addr1);
strcpy(r->addTab[conn+1 /*or something*/], addr2);
}
ori0n
  • 1
  • 3