Bryce Ramgovind
Bryce Ramgovind

Reputation: 3257

2D arrays passed through functions in c

I'm having a problem with my program. I need my program to read from a text file, the first consists of the dimensions of the 2d array the rest is the contents of the array. I have coded the readWord function which reads from textfiles and it works but when i do anything on the main function with the array it crashes. Please could you help.

int main()

{
       int num_it, cols, rows;
       char** myworld;

       num_it = readWorld(myworld,&cols, &rows);

       myworld[1][2]='x';/*it crashes when i make this statement*/

}


int readWorld(char** world, int* width,int* height)
{
  int result=0,i,cols=0,rows=0;
  char buff[25];

   FILE* file = fopen ("world.txt", "r");

   fscanf(file, "%d %d %d\n", width, height, &result);

   /*Dynamic allocation*/
   world = (char**)malloc(*(height)* sizeof(char*));
    for(i=0;i<*height;i++)
    {
        world[i] = (char*)malloc(*width*sizeof(char));
    }

    /*store data in array*/
    while(fgets(buff, sizeof buff, file) != NULL)
    {
       if (strlen(buff) >1){

       for(cols=0; cols<=(strlen(buff)); ++cols)
       {
          world[rows][cols] = buff[cols];
       }      
       ++rows;
    }
}

fclose(file);

return result;

}

Upvotes: 1

Views: 175

Answers (2)

Bathsheba
Bathsheba

Reputation: 234655

You need to allocate the memory for myworld in the actual caller!

What's happening here is that you are passing the pointer by value to the function.

The pointer value is changed by the function but that's not going to adjust the one in the caller.

Two options: use a triple indirection (ie pass a pointer to the the pointer) or allocate in the main sub. I prefer the latter, mainly because you can control the memory deallocation in a more symmetrical manner; even if you fixed this problem your code still has the memory leak.

What you're experiencing is undefined behaviour as you are attempting to access memory your program does not own.

Upvotes: 2

Nik Bougalis
Nik Bougalis

Reputation: 10613

Your myworld variable in main is never initialized and points to junk, so when you try to access it bad things happen. Think about why: you are passing a copy of the variable to readWorld. You correctly allocate memory inside there, and make the copy point to it, but the original pointer (in main) still points to whatever random location it pointed to before.

If you want the memory for it to be allocated inside the readWorld function and made accessible via the myworld variable in main then you must pass a pointer to myworld to readWorld; in other words, you must pass a triple pointer.

Try this:

int readWorld(char*** world, int* width,int* height)
{ 
    char **tempworld = malloc(...);

    // do whatever

    *world = tempworld;

    return result;
}

int main()
{
    char **myworld = NULL;

    readWorld(&myworld, ...);

    return 0;
}

Upvotes: 1

Related Questions