2017-04-09 15 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(メモリリーク検出ツールである)
はリークを検出します。
ほとんどの場合、それはです。が漏れています。 C言語はあなたのためにGarbage Collectionをしません。

This Q&Aは、どのメモリが自動的に解放され、どのメモリが解放されるのかを明確に示します。

リークディテクタを静かにする場合は、メモリを解放する必要はありません。 メモリを解放することをお勧めします。 - n.m.

私の意見では、常にメモリを解放してください。
メモリリークが数バイトであっても、実際には速く蓄積する可能性があります。

+0

私たちは一度割り当てられたメモリについて言及しており、プログラムの最後まで必要です。あなたはそれを解放しますが、それが蓄積するわけではありません。 –

+0

@ n.m。私はそれが非常に良い理由だと思う。それ以外の場合、問題は何ですか?セキュリティ? – YukiNyaa

+0

これはまったく累積しません。一度だけ割り当てられます。解放すると、プログラムはとにかく終了します。理由はありません。私が言ったように、そのような記憶を解放する理由は、あなたのためにあなたのログをきれいに保っているということです。あなたが本当に問題に陥るのは、それが騒音で失われるためです。 –

関連する問題