我用SDL api編寫了一個簡單的蛇遊戲,遊戲中有一處內存泄漏,因爲遊戲運行大約10分鐘後,它佔用了50MB的內存,並且仍在擴展。我盡我所能找到了泄漏點,但找不到它。我嘗試過使用Dr Memory,但是它產生的日誌不是我完全可以理解的。解讀DrMemory日誌,內存泄露
這裏的日誌中的問題: https://docs.google.com/file/d/0BwXrdShTcyjENmgyR2lrbTJ1aGc/edit?usp=sharing
我用SDL api編寫了一個簡單的蛇遊戲,遊戲中有一處內存泄漏,因爲遊戲運行大約10分鐘後,它佔用了50MB的內存,並且仍在擴展。我盡我所能找到了泄漏點,但找不到它。我嘗試過使用Dr Memory,但是它產生的日誌不是我完全可以理解的。解讀DrMemory日誌,內存泄露
這裏的日誌中的問題: https://docs.google.com/file/d/0BwXrdShTcyjENmgyR2lrbTJ1aGc/edit?usp=sharing
在您的Dr. Memory日誌中,您可以看到您有3次錯誤,計數約爲2899次。 的錯誤是:
Error # 154: 2899
Error # 155: 2899
Error # 369: 2898
所以,如果你看一下錯誤:
Error #154: GDI USAGE ERROR: same bitmap 0x46052c24 selected into two different DC's 0x08012c43 and 0xbe012c3e
# 0 SDL.dll!SDL_UnregisterApp +0x3063 (0x681304c3 <SDL.dll+0x304c3>)
# 1 SDL.dll!SDL_UpdateRect +0x69 (0x68125d7a <SDL.dll+0x25d7a>)
# 2 SDL.dll!SDL_Flip +0x52 (0x68125ff3 <SDL.dll+0x25ff3>)
# 3 draw() [L:/git/snake/src/main.cpp:133]
# 4 SDL_main [L:/git/snake/src/main.cpp:92]
# 5 console_main [./src/main/win32/SDL_win32_main.c:315]
# 6 [email protected] [./src/main/win32/SDL_win32_main.c:398]
# 7 main [L:/git/snake/src/main.cpp:211]
Note: @0:00:04.148 in thread 3940
Error #155: GDI USAGE ERROR: DC 0x08012c43 that contains selected object being deleted
# 0 system call NtGdiDeleteObjectApp
# 1 GDI32.dll!DeleteDC +0xb6 (0x75b1596a <GDI32.dll+0x1596a>)
# 2 GDI32.dll!DeleteDC +0x11 (0x75b158c5 <GDI32.dll+0x158c5>)
# 3 SDL.dll!SDL_UnregisterApp +0x30c9 (0x6813052a <SDL.dll+0x3052a>)
# 4 SDL.dll!SDL_UpdateRect +0x69 (0x68125d7a <SDL.dll+0x25d7a>)
# 5 SDL.dll!SDL_Flip +0x52 (0x68125ff3 <SDL.dll+0x25ff3>)
# 6 draw() [L:/git/snake/src/main.cpp:133]
# 7 SDL_main [L:/git/snake/src/main.cpp:92]
# 8 console_main [./src/main/win32/SDL_win32_main.c:315]
# 9 [email protected] [./src/main/win32/SDL_win32_main.c:398]
#10 main [L:/git/snake/src/main.cpp:211]
Note: @0:00:04.149 in thread 3940
Error #369: LEAK 60 direct bytes 0x04c09070-0x04c090ac + 0 indirect bytes
# 0 SDL.dll!SDL_CreateRGBSurface +0x8a (0x681250cb <SDL.dll+0x250cb>)
# 1 SDL_ttf.dll!TTF_RenderUNICODE_Solid +0xa6 (0x6f4c2e87 <SDL_ttf.dll+0x2e87>)
# 2 SDL_ttf.dll!TTF_RenderText_Solid +0x62 (0x6f4c3253 <SDL_ttf.dll+0x3253>)
# 3 draw() [L:/git/snake/src/main.cpp:130]
# 4 SDL_main [L:/git/snake/src/main.cpp:92]
# 5 console_main [./src/main/win32/SDL_win32_main.c:315]
# 6 [email protected] [./src/main/win32/SDL_win32_main.c:398]
# 7 main [L:/git/snake/src/main.cpp:211]
看來,你在一些循環分配新的內存,但忘記解除分配。
對於錯誤#369,標記爲LEAK:致電TTF_RenderText_Solid()
後,您需要致電SDL_FreeSurface()
。
內存泄漏是由錯誤的動態分配使用(或用指針搞亂)引起的。我想你沒有使用任何自定義動態分配爲一個小蛇遊戲,所以我想你搞砸了SDL_Surface *
東西。
檢查您在哪裏使用SDL_Surface *
。是否使用任何代碼在主遊戲循環中創建(分配)新的曲面?
SDL功能的新表面通常是SDL_LoadBMP()
,SDL_GetRGBSurface()
和SDL_SetVideoMode()
。你在主遊戲循環中使用它們中的任何一個嗎?他們通常不應該在。
或者您可能使用了任何動態分配?檢查你所有的指針!
我消除了所有不需要的指針。剩下的唯一指針是我的蛇類指針和sdl的幾個指針。我將我的SDL函數放在Lazy Foo的SDL教程上。 – Krzaku 2013-03-12 18:15:07
然後,正如我所說的,檢查您的SDL指針,它們不應受主循環內的「SDL_GetRGBSurface」和「SDL_LoadBMP」影響。如果它們不是,那麼蛇類指針就是原因。你在主循環中使用'new'作爲你的蛇類嗎?如果是的話,那肯定是原因。 'new'運算符是**動態分配**。 – pampeho 2013-03-12 18:20:04
在主循環的任何地方都不使用'new'。 – Krzaku 2013-03-12 18:22:44
也許你可能會切換到Linux並使用'valgrind'? – 2013-03-12 17:56:15
也許有些代碼..它聽起來像一個循環問題 – iKlsR 2013-03-12 18:01:08
根據日誌你有很多內存泄漏。例如,看看這裏是什麼:'#5 load_image()[L:/git/snake/src/main.cpp:144] #6 load_files()[L:/ git/snake/src/main。 cpp:192]' – varnie 2013-03-12 18:09:47