2011-08-17 93 views
1

我運行了createNewBoard,它調用了createNewMatrix,並且我退出程序,並且出現內存泄漏,我找不到。這裏的代碼在c中找不到內存泄漏

BoardP createNewBoard(int width, int high) 
{ 
    BoardP board = (BoardP) malloc(sizeof(Board)); 

    if (board == NULL) 
    { 
     reportError(MEM_OUT); 
     return NULL; 
    } 
    board->height = high; 
    board->width = width; 
    board->matrix = createNewMatrix(width,high); 
    printf("%c",board->matrix[1][1]); 
    if (board->matrix == NULL) 
    { 
     reportError(MEM_OUT); 
     freeBoard(board); 
    return NULL; 
    } 
return board; 
} 

static char** createNewMatrix(int width, int height){ 
    char** newMatrix = (char**) calloc(height,sizeof(char*)); 
    int i; 
    for (i=0; i<height; i++) 
    { 
     newMatrix[i] = (char*) calloc(width,sizeof(char)); //LINE 71 
     if (newMatrix[i] == NULL) 
     { 
      int j; 
      for (j=0; j<i; j++) 
      { 
       free(newMatrix[j]); 
      } 
      free(newMatrix); 
      return NULL; 
     } 
    } 
    return newMatrix; 
} 

這讓我瘋狂。我所做的只是創建一個指向Board結構(指向整數和二維指針數組)的指針,並且存在內存泄漏。這裏的消息:

==10436== HEAP SUMMARY: 
==10436==  in use at exit: 100 bytes in 10 blocks 
==10436== total heap usage: 12 allocs, 2 frees, 196 bytes allocated 
==10436== 
==10436== 100 bytes in 10 blocks are definitely lost in loss record 1 of 1 
==10436== at 0x4C2380C: calloc (vg_replace_malloc.c:467) 
==10436== by 0x4008C6: createNewMatrix (Board.c:71) 
==10436== by 0x40081E: createNewBoard (Board.c:55) 
==10436== by 0x4007C6: createNewDefaultBoard (Board.c:37) 
==10436== by 0x400F0C: main (PlayBoard.c:11) 
==10436== 
==10436== LEAK SUMMARY: 
==10436== definitely lost: 100 bytes in 10 blocks 
==10436== indirectly lost: 0 bytes in 0 blocks 
==10436==  possibly lost: 0 bytes in 0 blocks 
==10436== still reachable: 0 bytes in 0 blocks 
==10436==   suppressed: 0 bytes in 0 blocks 

它指向我的第71行,它調用矩陣中的行calloc。當程序退出時,它會調用freeBoard:

void freeBoard(BoardP board) 
{ 
    if (board != NULL) 
    { 
     if(board->matrix != NULL) 
     { 
      free(board->matrix); 
     } 
     free(board); 
    } 
} 

任何想法爲什麼我有內存泄漏?謝謝!

回答

6

在釋放matrix之前,您必須先釋放各條線。

for (i=0; i<height; i++) 
{ 
    free(board->matrix[i]); 
} 
+0

太好了!但是這裏有一個問題:我的calloc只能分配矩陣中的部分行嗎?我能夠通過預期的線路數量並將其全部釋放嗎?還是必須知道分配了多少條線路? – yotamoo

+0

從頭開始將所有行設置爲NULL。如果'calloc'失敗,它也返回NULL。在C中,它對'free(NULL)'是合法的。 – cnicutar

0

對矩陣你分配所有元素的內存,但你不會在功能freeBoard()解除分配它們。

0

我沒有看到混淆,你清楚不要免費大小的任何width*sizeof(char)陣列。由輸出去,既heightwidth是10

0

你免費free(board->matrix)需要釋放你是如何釋放它在createNewMatrix空校驗矩陣。

void freeBoard(BoardP board) 
{ 
    if (board != NULL) 
    { 
     if(board->matrix != NULL) 
     { 
      for (int i = 0; i < board->height; i++) 
      { 
       free(board->matrix[i]); 
      } 
      free(board->matrix); 
     } 
     free(board); 
    } 
} 

它可以更容易地創建一個freeMatrix函數接受的高度,或創建維護其自己的高度和寬度的矩陣結構。

0

board->matrix是一個指向你已經動態分配的指針的指針。首先,您使用calloc分配第一個維度,併爲每個索引分配,您使用calloc分配其他維度。因此,你有一個指向內存塊的指針數組,你必須釋放每個指針所指示的每個塊。

在您的代碼中,您只需釋放第一個維度,其每個位置指向不同的塊。另一方面,第二維中的這些塊不會被釋放。

你應該做這樣的事情:

void freeBoard(BoardP board) 
{ 
    int i; 
    if (board != NULL) 
    { 
     if(board->matrix != NULL) 
     { 
      for (i=0; i<board->height; i++); 
       free(board->matrix[i]); 
     } 
     free(board); 
    } 
} 

我已經試過的事情in this post

+0

嗨,說calloc未達到'board-> height'之前失敗,我不知道分配了多少行。如果我嘗試釋放未分配的行,會發生什麼情況? – yotamoo

+0

這仍然會導致int泄漏,因爲如果沒有分配'board-> matrix' – Joe

+0

,則將第一維中的所有指針初始化爲NULL。如果分配失敗,那麼在釋放時,您可以檢查'board-> matrix [i]'是否爲NULL,然後調用'free'。你可以在'free'中傳遞NULL指針,如果你將NULL傳遞給'free',就不會執行任何操作。 – phoxis