2017-04-09 173 views
0
struct game_t { 
    int playercount; 
    int board_width, board_height; 
    int turn_of;//player number 
    int eleminatedPlayer[MAX_PLAYERS]; 
    int turn; 
    int cellcnt[MAX_PLAYERS]; 

    grid_t** board; 

    move_t* moves; 
}; 

game_t* new_game(int width, int height, int playercount) 
{ 
    int i; 
    game_t* newgame; 
    newgame = (game_t*)calloc(1,sizeof(game_t)); // <line 181 

    newgame->board_height = height; 
    newgame->board_width = width; 
    newgame->playercount = playercount; 
    newgame->turn_of = 0;//Red(player 0) 
    zero_fill_arr((char*)newgame->eleminatedPlayer, sizeof(int)*MAX_PLAYERS); 
    zero_fill_arr((char*)newgame->cellcnt, sizeof(int)*MAX_PLAYERS); 

    newgame->moves = (move_t*)calloc(MAX_MOVES, sizeof(move_t)); 


    newgame->board = (grid_t**)calloc(width, sizeof(grid_t**)); 

    for (i = 0; i < width; i++) 
    { 
     newgame->board[i] = (grid_t*)calloc(height, sizeof(grid_t)); 
    } 

    return newgame; 
} 

此代碼每次調用calloc時都有內存泄漏。
實施例:爲什麼會有內存泄漏? (C)

WARNING: Visual Leak Detector detected memory leaks! 
---------- Block 1 at 0x00EA5B20: 76 bytes ---------- 
    Leak Hash: 0xE1234C8B, Count: 1, Total 76 bytes 
    Call Stack (TID 3264): 
    ucrtbased.dll!calloc() 
    atoms.c (181): Atoms.exe!new_game() + 0xC bytes 
    atoms.c (120): Atoms.exe!main() + 0x1A bytes 
    f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (64): Atoms.exe!invoke_main() + 0x1B bytes 
    f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (253): Atoms.exe!__scrt_common_main_seh() + 0x5 bytes 
    f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl (296): Atoms.exe!__scrt_common_main() 
    f:\dd\vctools\crt\vcstartup\src\startup\exe_main.cpp (17): Atoms.exe!mainCRTStartup() 
    KERNEL32.DLL!BaseThreadInitThunk() + 0x24 bytes 
    ntdll.dll!RtlSubscribeWnfStateChangeNotification() + 0x439 bytes 
    ntdll.dll!RtlSubscribeWnfStateChangeNotification() + 0x404 bytes 
    Data: 
    02 00 00 00 03 00 00 00 03 00 00 00 00 00 00 00  ........ ........ 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ........ ........ 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ........ ........ 
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ........ ........ 
    00 00 00 00 60 05 EB 00 58 6D EB 00     ....`... Xm...... 

其他信息:

該函數的調用一次。

這段代碼調用函數:game_session = new_game(w,h,playerno);
game_session用NULL(0)初始化。

+2

由於每個未分配的內存都被泄漏檢測器視爲內存泄漏。這是一個。 –

+0

@ n.m。所以,分配的內存必須在代碼的**結尾被釋放**? – YukiNyaa

+0

不,您必須在釋放最後一個指針之前釋放內存。這可能是該計劃的結尾。 – Yunnosch

回答

0

所以,最後我學到了什麼:

Visual Leak DetectorLeakSanitizer(這是內存泄漏檢測工具)
檢測泄漏時,內存不釋放在主函數返回。
因爲大多數,它是IS泄漏。 C語言不會爲你做Garbage Collection

This Q&A清楚地顯示哪些內存被自動釋放,哪些不是。

你真的不必釋放內存,如果只是爲了讓泄漏檢測器靜音。 但這是一個很好的做法,釋放內存 - n.m.

在我看來,總是釋放內存。
即使幾個字節的內存泄漏可能會非常快速地累積。

+0

我們正在討論分配一次的內存,直到程序的最後。你釋放它,但不是因爲它累積。 –

+0

@ n.m。我認爲這是一個很好的理由。除此之外,問題是什麼?安全? – YukiNyaa

+0

它根本沒有積累,它只被分配一次,當你釋放它時,程序終止,所以它不能成爲一個理由。正如我所說,釋放這種記憶的原因是保持你的日誌清潔,因爲你沒有,你遲早會錯過一個真正的問題,因爲它會在噪音中丟失。 –