1

i have a school assignment of writing some functions for the game of life and I am stuck right at the beginning:

Implement function 'createField' that allocates the needed space for the 'Field' structure that holds the game field, and for a two-dimensional array of dimensions given in parameters 'xsize' and 'ysize'. Each cell in the field must be initialized to 'DEAD' state, as well as the 'xsize' and 'ysize' fields in the structure.

Note: the tests assume that the rows (y-axis) of the field are the first dimension of the array (and allocated first), and the columns are the second dimension. I.e., the cells are indexed as [y][x].

You will also need to implement function 'releaseField' that frees the memory allocated by createField(). The tests will use this function for all memory releases, so failing to implement this will result in Valgrind errors about memory leaks

  typedef enum {
        DEAD,
        ALIVE
    } State;

    typedef struct {
        unsigned int xsize, ysize;
    State **cells;
     } Field;

The first task is to write functions that create the field and release it

Field *createField(unsigned int xsize, unsigned int ysize)
{
    (void) xsize; 
    (void) ysize;
    Field *create = malloc(sizeof( Field));
    create->xsize=xsize;
    create->ysize=ysize;
// for this part I don't know the syntax + I don understand what I am doing
    create->cells = malloc (ysize*sizeof(State*));
    for(unsigned int j=0;j<ysize;j++)
    {
        create->cells[j] = malloc(xsize*sizeof(State));
    }
    return create;   
}

My cleanup function:

void releaseField(Field *f)
{
    (void) f;
    for(unsigned int i=0;i<f->ysize;i++)
        free(f->cells[i]);
    free(f->cells);
    free (f);
}

I am getting valgrind errors:

==374== Conditional jump or move depends on uninitialised value(s)
==374==    at 0x40172C: test_createField (test_source.c:26)
==374==    by 0x4058A0: srunner_run_all (in /tmc/test/test)
==374==    by 0x402276: tmc_run_tests (tmc-check.c:122)
==374==    by 0x401F2F: main (test_source.c:225)
==374==  Uninitialised value was created by a heap allocation 
==374==    at 0x4C244E8: malloc (vg_replace_malloc.c:236) 
==374==    by 0x402960: createField (gameoflife.c:21) 
==374==    by 0x401662: test_createField (test_source.c:16) 
==374==    by 0x4058A0: srunner_run_all (in /tmc/test/test) 
==374==    by 0x402276: tmc_run_tests (tmc-check.c:122) 
==374==    by 0x401F2F: main (test_source.c:225) 
==374==  
==375== Conditional jump or move depends on uninitialised value(s) 
==375==    at 0x4017F5: countlive (test_source.c:42) 
==375==    by 0x401921: test_initField (test_source.c:62) 
==375==    by 0x4058A0: srunner_run_all (in /tmc/test/test) 
==375==    by 0x402276: tmc_run_tests (tmc-check.c:122) 
==375==    by 0x401F2F: main (test_source.c:225) 
==375==  Uninitialised value was created by a heap allocation 
==375==    at 0x4C244E8: malloc (vg_replace_malloc.c:236) 
==375==    by 0x402960: createField (gameoflife.c:21) 
==375==    by 0x4018F3: test_initField (test_source.c:57) 
==375==    by 0x4058A0: srunner_run_all (in /tmc/test/test) 
==375==    by 0x402276: tmc_run_tests (tmc-check.c:122) 
==375==    by 0x401F2F: main (test_source.c:225) 
==375==  
==375== Conditional jump or move depends on uninitialised value(s) 
==375==    at 0x401820: countlive (test_source.c:44) 
==375==    by 0x401921: test_initField (test_source.c:62) 
==375==    by 0x4058A0: srunner_run_all (in /tmc/test/test) 
==375==    by 0x402276: tmc_run_tests (tmc-check.c:122) 
==375==    by 0x401F2F: main (test_source.c:225) 
==375==  Uninitialised value was created by a heap allocation 
==375==    at 0x4C244E8: malloc (vg_replace_malloc.c:236) 
==375==    by 0x402960: createField (gameoflife.c:21) 
==375==    by 0x4018F3: test_initField (test_source.c:57) 
==375==    by 0x4058A0: srunner_run_all (in /tmc/test/test) 
==375==    by 0x402276: tmc_run_tests (tmc-check.c:122) 
==375==    by 0x401F2F: main (test_source.c:225) 
==375== 

Please help me I spent so many hours searching but couldn't wrap my mind around it.

PS: I cannot modify anything except the content of the function..

7
  • 2
    Post the errors. verbatim, and in the question. I suspect this code is identified as the allocation point of memory leaks because you never properly clean up all these allocations elsewhere. Besides the useless (void)xsize; and (void)ysize;, the only other things wrong with this specific code are failure to validate your allocations succeeded. and using State* and State instead of int * and int, and likely neither will cause the mentioned, but unposted, "valgrind errors". (props for running valgrind, btw; considerably more effort than most people take). Commented Mar 16, 2015 at 1:02
  • (void) xsize; What is this? Commented Mar 16, 2015 at 1:58
  • @PatrickCollins its supposed to shut the compiler warning for unused variables off. It can be safely removed. Commented Mar 16, 2015 at 2:01
  • @FDinoff Why would anyone want to do that? Commented Mar 16, 2015 at 2:02
  • @PatrickCollins Most likely it was given in the template code so it could compile without warnings. I've used it for ignoring arguments when the function was required to have the argument (from lets say a function pointer) but I had no additional data to pass to the function. Commented Mar 16, 2015 at 2:04

2 Answers 2

3

You didn't do this part. "Each cell in the field must be initialized to 'DEAD' state, as well as the 'xsize' and 'ysize' fields in the structure."

The data returned from malloc is uninitialized. So it could be set to anything (it does not default to DEAD.) So you need to initialize everything in the two dimensional array to DEAD.


Other comments. You should check to make sure that malloc doesn't return NULL. If it does it means that you ran out of memory and want to handle the error instead of getting a segmentation fault.

Also you can safely remove the (void) var; statements as they are there to silence the warning about unused variables. However you are currently using them and they serve no purpose.

Sign up to request clarification or add additional context in comments.

Comments

2

The assignment says "Each cell in the field must be initialized to 'DEAD' state". You are not doing that. That means that when some other code accesses a cell, it is reading a garbage value.

After you allocate the row, you need to loop through and set each cell to DEAD. Something like this should work:

create->cells[j] = malloc(xsize*sizeof(State)); // Your existing line
for(unsigned int i=0;i<xsize;i++)
  create->cells[j][i] = DEAD;

2 Comments

thank you guys a lot it was very helpful! how can I vote you or something??
@KhaledAbdallah you need 15 reputation to upvote. Come back when you get it. For now just choose the answer you feel helped you the most for the checkmark.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.