繁体   English   中英

对象破坏时内存泄漏

[英]Memory leak on object destruction

我有一个玩具项目,它是一个游戏引擎。 它使用SDL2和C ++ 11。 在下面的代码中,我尝试在析构函数中创建一个清除内存的对象。 但出了问题,一些内存泄漏。 我究竟做错了什么?

示例是触发泄漏的最小工作代码。 我认为它的工作方式如下:类的实例Game on costruction创建了SDLEngineGraphics实例(按此顺序),两者都分配了一些内存。 game对象被破坏时,它会调用GraphicsSDLEngine析构函数(按此顺序)。 如果我在这两个析构函数中添加一些打印,它们将按所需顺序打印。 但是valgrind认为由SDL_Init()SDL_CreateWindow()分配的内存被泄露。

编辑:这可能是valgrind的行为。 我在相当基本的SDL示例中看到了类似的问题和类似的警告: 为什么valgrind说基本的SDL程序泄漏了内存?

SRC /泄漏TEST.CPP:

#include <SDL2/SDL.h>
#include <stdexcept>

class SDLEngine {
public:
    SDLEngine() {
        if (SDL_Init(SDL_INIT_VIDEO) != 0) {
            throw std::runtime_error("SDL_Init"); // line 7
        }
        if (SDL_ShowCursor(SDL_DISABLE) < 0) {
            throw std::runtime_error("SDL_ShowCursor");
        }
    }
    ~SDLEngine() {
        SDL_Quit();
    }
};

class Graphics {
public:
    Graphics() :
        sdlWindow{SDL_CreateWindow(
                    "LeakTest",
                    SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                    320, 240,
                    0
                    )} // line 27
    {
        if (sdlWindow == nullptr) {
            throw std::runtime_error("SDL_CreateWindow");
        }
    }
    ~Graphics() {
        SDL_DestroyWindow(sdlWindow);
    }
    Graphics(const Graphics&)=delete;
    Graphics& operator=(const Graphics&)=delete;
private:
    SDL_Window *sdlWindow;
};

class Game {
public:
    Game() :
        sdlEngine_(),
        graphics_() // line 46
    {
        SDL_Event event;
        bool running{true};
        while (running) {
            while (SDL_PollEvent(&event)) {
                switch (event.type) {
                case SDL_KEYDOWN:
                    running = false;
                    break;
                default:
                    break;
                }
            }
        }

    }
    ~Game() {}
private:
    const SDLEngine sdlEngine_;
    Graphics graphics_;
};

int main() {
    Game game; // line 70
    return 0;
}

Makefile文件:

CXX := g++
MKDIR := mkdir -p
CXXFLAGS += `pkg-config --cflags sdl2 SDL2_image`
CXXFLAGS += -Wall -Werror -Wextra -Weffc++ -pedantic -std=c++0x -g
LDFLAGS += `pkg-config --libs sdl2 SDL2_image`
PROG := bin/leak-test
OBJS := $(patsubst src/%.cpp,obj/%.o, $(wildcard src\/*.cpp))
#                         escaped to fool SO parser ^
.PHONY: all clean

all: build

build: $(PROG)

clean:
    rm -rf $(PROG) $(OBJS)

$(PROG): obj/leak-test.o

$(PROG):
    @$(MKDIR) $(dir $@)
    $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^

obj/%.o : src/%.cpp
    @$(MKDIR) $(dir $@)
    $(CXX) $(CXXFLAGS) -c -MD -o $@ $<

Valgrind输出:

host:cave-test » valgrind --leak-check=full ./bin/leak-test 
==28815== Memcheck, a memory error detector
==28815== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==28815== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==28815== Command: ./bin/leak-test
==28815== 
==28815== 
==28815== HEAP SUMMARY:
==28815==     in use at exit: 66,235 bytes in 506 blocks
==28815==   total heap usage: 19,844 allocs, 19,338 frees, 44,931,400 bytes allocated
==28815== 
==28815== 20 bytes in 2 blocks are definitely lost in loss record 7 of 101
==28815==    at 0x4C274A0: malloc (vg_replace_malloc.c:291)
==28815==    by 0x5BF8829: strdup (strdup.c:42)
==28815==    by 0x7203666: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815==    by 0x7204474: _XimSetICValueData (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815==    by 0x71FFA69: _XimLocalCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815==    by 0x71E6044: XCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815==    by 0x5111CD2: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x51120F7: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x51055FF: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x510540F: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x507048E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x400D6E: SDLEngine::SDLEngine() (leak-test.cpp:7)
==28815== 
==28815== 20 bytes in 2 blocks are definitely lost in loss record 8 of 101
==28815==    at 0x4C274A0: malloc (vg_replace_malloc.c:291)
==28815==    by 0x5BF8829: strdup (strdup.c:42)
==28815==    by 0x7203666: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815==    by 0x7204474: _XimSetICValueData (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815==    by 0x71FFA69: _XimLocalCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815==    by 0x71E6044: XCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815==    by 0x5111CD2: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x51120F7: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x51055FF: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x400F11: Graphics::Graphics() (leak-test.cpp:27)
==28815==    by 0x401012: Game::Game() (leak-test.cpp:46)
==28815==    by 0x400D31: main (leak-test.cpp:70)
==28815== 
==28815== 104 bytes in 1 blocks are definitely lost in loss record 60 of 101
==28815==    at 0x4C274A0: malloc (vg_replace_malloc.c:291)
==28815==    by 0xD330A11: ??? (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815==    by 0xD309600: ??? (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815==    by 0xD305E7A: ??? (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815==    by 0xD30660F: glXChooseVisual (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815==    by 0x510ED0E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x510EF40: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x5103B65: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x51056FB: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x510540F: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x507048E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815==    by 0x400D6E: SDLEngine::SDLEngine() (leak-test.cpp:7)
==28815== 
==28815== LEAK SUMMARY:
==28815==    definitely lost: 144 bytes in 5 blocks
==28815==    indirectly lost: 0 bytes in 0 blocks
==28815==      possibly lost: 0 bytes in 0 blocks
==28815==    still reachable: 66,091 bytes in 501 blocks
==28815==         suppressed: 0 bytes in 0 blocks
==28815== Reachable blocks (those to which a pointer was found) are not shown.
==28815== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==28815== 
==28815== For counts of detected and suppressed errors, rerun with: -v
==28815== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 7 from 3)

事实证明,这个漏洞属于X11库中的SDL层。 这个bug很老,SDL开发人员都知道。 看到这个bugzilla线程: https ://bugzilla.libsdl.org/show_bug.cgi id = 2086

我现在关闭这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM