为什么会有内存泄漏? (C)

问题描述:

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

所以,最后我学到了什么:

Visual Leak DetectorLeakSanitizer(这是内存泄漏检测工具)
检测泄漏时,内存不释放在主函数返回。
因为大多数,它是IS泄漏。 C语言不会为你做Garbage Collection

This Q&A清楚地显示哪些内存被自动释放,哪些不是。

你真的不必释放内存,如果只是为了让泄漏检测器静音。 但这是一个很好的做法,释放内存 - n.m.

在我看来,总是释放内存。
即使几个字节的内存泄漏可能会非常快速地累积。

+0

我们正在讨论分配一次的内存,直到程序的最后。你释放它,但不是因为它累积。 –

+0

@ n.m。我认为这是一个很好的理由。除此之外,问题是什么?安全? – YukiNyaa

+0

它根本没有积累,它只被分配一次,当你释放它时,程序终止,所以它不能成为一个理由。正如我所说,释放这种记忆的原因是保持你的日志清洁,因为你没有,你迟早会错过一个真正的问题,因为它会在噪音中丢失。 –