【问题标题】:Why is there a memory leak? (C)为什么会出现内存泄漏? (C)
【发布时间】:2017-04-09 17:39:25
【问题描述】:
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 时,此代码都会发生内存泄漏。
示例:

    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)。

【问题讨论】:

  • 因为每个未释放的已分配内存都被泄漏检测器视为内存泄漏。这个是。
  • @n.m.所以,分配的内存必须在代码末尾释放?
  • 不,您必须在丢失最后一个指向它的指针之前释放内存。那可能是在程序结束时。
  • 你没有释放内存。内存泄漏不是(总是)致命的。但释放所有东西是一个很好的做法,即使只是为了让检漏仪静音。因为当您有真正的泄漏时,您可能会在“无关紧要”的误报噪音中错过它。
  • 在退出程序前释放所有内存后问题解决。谢谢大家!

标签: c memory-leaks


【解决方案1】:

所以,总结一下我学到的东西:

Visual Leak Detector,LeakSanitizer(内存泄漏检测工具)
当 main 函数返回时未释放内存时检测泄漏。
因为大多数情况下,它 IS 泄漏。 C语言不会为你做Garbage Collection

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

您真的不必释放内存,只要让检漏仪静音即可。 但释放内存是个好习惯 - 不准

在我看来,总是释放内存。
即使是几个字节的内存泄漏也会很快累积。

【讨论】:

  • 我们谈论的是分配一次的内存,直到程序结束时才需要。你释放它,但不是因为它积累。
  • @n.m.我认为这是一个很好的理由。除此之外,还有什么问题?安全吗?
  • 它根本不累积,它只被分配一次,当你释放它时,程序无论如何都会结束,所以这不是一个原因。正如我所说,释放这些内存的原因是保持日志清洁,因为你不这样做,你迟早会错过一个真正的问题,因为它会在噪音中丢失。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-07
  • 2011-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多