2011-12-31 111 views
1

我想用C++ 11的std :: tr1 :: shared_ptr來管理SDL_Surface指針。請注意,我沒有使用Boost。我已經爲shared_ptr定義了一個刪除器來使用SDL_FreeSurface。爲什麼我的shared_ptr泄漏內存?

聲明如下:

class Engine { 
private: 
    std::tr1::shared_ptr<SDL_Surface> _scr; 
    std::tr1::shared_ptr<SDL_Surface> _bg; 

定義(在發動機的構造函數),如:

_scr = std::tr1::shared_ptr<SDL_Surface>(SDL_SetVideoMode(Data::SCR_WIDTH, 
                  Data::SCR_HEIGHT, 
                 32, SDL_SWSURFACE), 
              SurfaceDeleter<SDL_Surface>()); 

    _bg = std::tr1::shared_ptr<SDL_Surface>(IMG_Load(Data::IM_BACKGROUND), 
             SurfaceDeleter<SDL_Surface>()); 

的定製刪除:

template<typename T> 
class SurfaceDeleter{ 
public: 
    void operator() (T*& d) const { 
    if(d){ 
     SDL_FreeSurface(d); 
    } 
    } 
}; 

持有的shared_ptr的唯一對象是引擎。 shared_ptr的使用,像這樣:

SDL_BlitSurface(_bg.get(), nullptr, _scr.get(), nullptr); 
    SDL_Flip(_scr.get()); 

Valgrind的結果:

==3648== 8 bytes in 2 blocks are definitely lost in loss record 16 of 292 
==3648== at 0x402A018: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3648== by 0x431FBE0: strdup (in /lib/libc-2.14.1.so) 

==3648== 1 bytes in 1 blocks are definitely lost in loss record 1 of 292 
==3648== at 0x402A018: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3648== by 0x494A590: _XlcDefaultMapModifiers (in /usr/lib/libX11.so.6.3.0) 
==3648== by 0x494A99A: XSetLocaleModifiers (in /usr/lib/libX11.so.6.3.0) 
==3648== by 0x4097CDB: ??? (in /usr/lib/libSDL-1.2.so.0.11.3) 
==3648== by 0x4083868: SDL_VideoInit (in /usr/lib/libSDL-1.2.so.0.11.3) 
==3648== by 0x40594D9: SDL_InitSubSystem (in /usr/lib/libSDL-1.2.so.0.11.3) 
==3648== by 0x42C3212: (below main) (in /lib/libc-2.14.1.so) 

==3648== 980 (68 direct, 912 indirect) bytes in 1 blocks are definitely lost in loss record 258 of 292 
==3648== at 0x402A102: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) 
==3648== by 0x49402A6: ??? (in /usr/lib/libX11.so.6.3.0) 
==3648== by 0x49407A2: ??? (in /usr/lib/libX11.so.6.3.0) 
==3648== by 0x494212F: ??? (in /usr/lib/libX11.so.6.3.0) 
==3648== by 0x49429BA: _XlcCreateLC (in /usr/lib/libX11.so.6.3.0) 
==3648== by 0x4965957: _XlcUtf8Loader (in /usr/lib/libX11.so.6.3.0) 
==3648== by 0x494A793: _XOpenLC (in /usr/lib/libX11.so.6.3.0) 
==3648== by 0x494A8F1: _XlcCurrentLC (in /usr/lib/libX11.so.6.3.0) 
==3648== by 0x4097CDB: ??? (in /usr/lib/libSDL-1.2.so.0.11.3) 
==3648== by 0x4083868: SDL_VideoInit (in /usr/lib/libSDL-1.2.so.0.11.3) 
==3648== by 0x40594D9: SDL_InitSubSystem (in /usr/lib/libSDL-1.2.so.0.11.3) 
==3648== by 0x42C3212: (below main) (in /lib/libc-2.14.1.so) 
+5

不要叫'SDL_FreeSurface'由'SDL_SetVideoMode'返回的指針。當你調用SDL_Quit時它會被釋放。請參閱「返回值」下的[文檔](http://sdl.beuc.net/sdl.wiki/SDL_SetVideoMode)。 – 2011-12-31 04:54:03

+0

我試着從_scr shared_ptr中刪除刪除器,但泄漏仍然存在。 – 2011-12-31 04:56:22

+6

這是不足夠的信息繼續下去。我們需要看看你如何使用共享指針。什麼對象持有它們,什麼對象治理它們*等等。另外,在C++ 11中沒有'std :: tr1 :: shared_ptr'這樣的東西;它只是'std :: shared_ptr'; TR1早於C++ 11,如果您使用C++ 11,則不應使用它。 – 2011-12-31 04:56:37

回答

2

運行的valgrind與--track-origins=yes因此它顯示你在哪裏泄漏的內存被分配。

你也可能需要使用--leak-check=full--leak-resolution=high(儘管後者應該是默認的)