2

So I have a code and when I run it, it hangs when I enter a size greater than 3. When it's exactly 3 it runs smoothly. I narrowed down the problem to malloc and free and I don't know what the problem is. I'm new at this so any help is appreciated.

do  //repeatedly ask the user to put a number between 3-9
{ 
 printf("Enter the size of the game board between 3-9: ");
 scanf("%d", &size);
}while(size<3 || size>9);

if((board = (char***)malloc(sizeof(char**)*size))==NULL)
  printf("Memory Allocation failed\n");
  for(i=0; i<size; i++)
  {
    if((board[i] = (char**)malloc(sizeof(char*)*size))==NULL)
     printf("Memory Allocation failed\n");
     for(j=0; j<size; j++)
     {
       if((board[i][j] = (char *)malloc(sizeof(char)*4))==NULL)  
         printf("Memory Allocation failed\n");
         strcpy(board[i][j], "Go");
     }   
 } 
/*************Some random code ***********/ 

free(board);
for(i=0;i<size;i++)
{
 free(board[i]);
 for(j=0;j<size;j++)
   free(board[i][j]);
}
4
  • 1
    The order of free() should be in exact reverse order of malloc(). Commented Apr 9, 2012 at 2:38
  • 1
    When you use 'free(board[i]);' you actually lose the pointer to the memory you have allocated so you can't use 'free(board[i][j]);'. Use free(board[i]); after the second for. Commented Apr 9, 2012 at 2:41
  • @Als: It doesn't have to be in the exact reverse order. If you have an array of 3 pointers, you can malloc them in the order 0, 1, 2, then free them in the same order. You just can't free a pointer before freeing what it points to. Commented Apr 9, 2012 at 4:18
  • @KeithThompson: True, It doesn't have to, but I consider it a good practice rather advice especially with multidimensional arrays for new users.Though it abstracts the purpose and the real reason which you quoted, it works flawlessly abstracting the details. Commented Apr 9, 2012 at 4:21

1 Answer 1

2

The problem is you access board after you freed it. You should release memory in exactly the reverse order that you malloc it.

An alternative approach is that you can allocate all the memory you need in a whole, like

 char ***board = NULL;
 char  **rows  = NULL;
 char   *data  = NULL;

 if((board = (char***)malloc(sizeof(char**)*size))==NULL)
  printf("Memory Allocation failed\n");
 if((rows = (char**)malloc(sizeof(char*)*size*size))==NULL)
     printf("Memory Allocation failed\n");
 if((data = (char *)malloc(sizeof(char)*size*size*4))==NULL)  
     printf("Memory Allocation failed\n");

 for (i = 0; i < size; i++) {
     int board_offset = i * size;
     board[i] = rows[board_offset];
     for (j = 0; j < size; j++) {
         int row_offset = board_offset + j;
         rows[row_offset] = data[row_offset * 4];
         stcpy(data[row_offset * 4], "GO");
     }
 }

 free(board);
 free(rows);
 free(data);
Sign up to request clarification or add additional context in comments.

13 Comments

hey just have a question. Is it common to check for malloc failure? It almost never happens (unless you corrupt memory or actually run out of it) and I believe it will be adding a considerable expense to if() check every malloc.
@Lefteris Agree, and I seldom check it to be frank. I just follow the style from original post:). However, it is necessary for robust code I think.
Oh I did not notice that he did so in the OP too. Nice to see you agree. Well it depends on what you mean by robust code. I mean if I was to if() check every malloc I guess using another language would be better :P
@Lefteris: Not necessarily, you could simply wrap malloc in a function that exits on error, you'll still only be calling one function to allocate memory, it'll just have a different name. You shouldn't continue the way the OP does if malloc fails.
@AusCBloke Yes ofcourse you can wrap it in a function or even make a neat macro out of it but this is the point I am trying to make. You are adding additional function calling overhead to every malloc call. It all depends on where you wanna set the tradeoff between efficiency and safer programming I suppose. I might have been checking malloc if I had gotten more failed malloc calls, but in the systems I have worked in malloc only failed if I had made a programming error before and corrupted memory. How would you handle a malloc failure in a real program other than just quit?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.