2011-12-31 3 views
1

C++ 11의 std :: tr1 :: shared_ptr을 사용하여 SDL_Surface 포인터를 관리하려고합니다. 참고, 나는 부스트를 사용하지 않는다. SDL_FreeSurface를 사용하기 위해 shared_ptr에 대한 Deleter를 정의했습니다. (같은 엔진의 ctor에의) 정의내 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>()); 

사용자 정의 Deleter가 :

처럼 선언

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_SetVideoMode''에 의해 반환 된 포인터에'전화 SDL_FreeSurface'하지 마십시오 사용할 수도 있습니다. 'SDL_Quit'를 호출하면 해제됩니다. "반환 값"에서 [the docs] (http://sdl.beuc.net/sdl.wiki/SDL_SetVideoMode)를 참조하십시오. –

+0

_scr shared_ptr에서 삭제기를 시도했지만 누수가 여전히 존재합니다. –

+6

이 정보는 아직 충분하지 않습니다. 공유 포인터를 사용하는 방법을 알아야합니다. 어떤 객체가 그 객체를 유지하고, 어떤 객체가 그 객체를 관리하는지 등등. 또한, C++ 11에서는'std :: tr1 :: shared_ptr'과 같은 것이 없습니다. 그것은 단지'std :: shared_ptr'입니다; TR1은 C++ 11보다 먼저 나오므로 C++ 11을 사용하는 경우에는 사용하지 말아야합니다. –

답변

2

실행 Valgrind의를 누수 된 메모리가 할당 된 위치 --track-origins=yes 그래서 당신을 표시와 함께.

는 또한 --leak-check=full--leak-resolution=high이 (후자는해야하지만 기본)

관련 문제