我是否会产生内存泄漏? C ++,Pointers New / delete

时间:2017-01-23 19:03:52

标签: c++

我对以下内容不太确定:

我在头文件中创建指向Gui_Modal_Window对象的指针:

editor.h

 Gui_Modal_Window* gui_modal_window_map_saved;

在我的cpp文件正文中,我正在创建一个新的模态窗口(当用户点击特定按钮时......)

editor.cpp

gui_modal_window_map_saved = new Gui_Modal_Window("Map saved", "The map has been saved.");

要再次删除Modal窗口,我使用以下方法:

void Gui::delete_element(Gui* elem) {
    delete elem;
    elem = NULL;
}

我想知道我是否在这里创建内存泄漏,因为我的Visual Studio快照显示,在创建模态窗口之前,分配不会减少到它们的位置。

(参见附图,截图显示了启动程序时的分配(1),创建模态窗口(2)后再次删除该模态窗口后(3))。

Allocations

编辑2

我遵循了jaggedSpire的建议,用智能指针替换了所有新的/删除原始指针。而且我认为它确实改变了一些东西。查看新的附加图像 - 创建之前和关闭gui显示之后的分配数量,新分配的数量与删除的分配数量相同。我没有剖析专家 - 我在某种程度上是正确的还是这只是一个完全随意的事情?

Allocation with smart pointers

修改

好的,这是项目中的一些代码。我已经删除了一些我认为不必要的元素,但如果我错了,请纠正我。

Gui.h

#pragma once
#include <string>
#include <vector>
#include <map>
#include "Gui_.h"

class Gui {

private:
    static std::vector<Gui*> g_elements;            // static list of gui elements
    static std::vector<g_event> g_events;           // static map of gui events

protected:
    std::vector<Gui*> siblings;                     // holds each element's siblings

    int id;

    void static add(Gui* element);
    void static remove(Gui* element);
    void virtual calculate_size() { return; };

public:
    Gui();
    virtual ~Gui();

    void show();
    void hide();

    void add_element(Gui* elem);
    void virtual update_element() { return; }
    int get_element_count();

    void add_event(int event_id, Gui &elem);
    g_event get_event();

    void update();
    void virtual render();

};

Gui.cpp

#include "stdafx.h"
#include "settings.h"
#include "Input.h"
#include "Gui.h"


std::vector<Gui*> Gui::g_elements;
std::vector<g_event> Gui::g_events;

//
Gui::Gui() {
    printf("new gui");
    // Some graphic engine inits..
}


//
Gui::~Gui() {

}


//
int Gui::get_element_count() {
    return g_elements.size();
}


//
void Gui::update() {

    // Update each element and it's siblings
    if (g_elements.size() > 0) {
        for (auto& g : g_elements) {
            g->update_element();
        }
    }

}


//
void Gui::render() {

    if (g_elements.size() > 0) {
        for (auto& g : g_elements) {
            g->render();
        }
    }

}


//
void Gui::add(Gui* element) {
    g_elements.push_back(element);
}


//
void Gui::remove(Gui* element) {

    int i;
    for(i=0;i<g_elements.size();i++) {

        if (g_elements[i] == element) {
            g_elements.erase(g_elements.begin() + i);
        }
    }

}


//
void Gui::add_element(Gui* element) {

    siblings.push_back(element);
    // some assignments to the sibling..

    printf("\nAssigned an element to another element\n");

}


//
void Gui::add_event(int event_id, Gui& elem) {

    g_events.push_back({ event_id, &elem });

}


//
g_event Gui::get_event() {

    if (g_events.size() > 0) {
        g_event g = g_events.back();
        g_events.pop_back();
        return g;
    }
    else
        return {};
}

Gui_Modal_Window.h

#pragma once
#include <string>
#include <vector>
#include <map>
#include "Gui.h"

class Gui_Modal_Window : public Gui {

protected:
    std::string caption;
    std::string message;
    void virtual calculate_size() override;

public:
    Gui_Modal_Window(std::string caption, std::string message);
    ~Gui_Modal_Window() override;

    void update_element() override;
    void render() override;

};

Gui_Modal_Window.cpp

#include "stdafx.h"
#include "settings.h"
#include "Input.h"
#include "Gui.h"
#include "Gui_Modal_Window.h"


//
Gui_Modal_Window::~Gui_Modal_Window() {

    // Delete all siblings (adopt parent's values)
    if (siblings.size() > 0) {
        for (auto &s : siblings) {
            delete s;
        }
    }

    remove(this);

    printf("deleted a gui modal");

}


//
Gui_Modal_Window::Gui_Modal_Window(std::string caption, std::string message) {
    add(this);

    this->caption = caption;
    this->message = message;

    this->calculate_size();

    //this->x = (screen_width / 2) - (this->w / 2);
    //this->y = (screen_height / 2) - (this->h / 2);

    this->id = get_element_count() + 1;

    printf("\nNEW MODAL WINDOW\n");

}


//
void Gui_Modal_Window::calculate_size() {

    // size calculations


}


//
void Gui_Modal_Window::update_element() {

    calculate_size();

    // Update all siblings (adopt parent's values)
    for (auto &s : siblings) {
        s->x = x + s->old_x;
        s->y = y + s->old_y;
        s->hidden = hidden;
    }

}


//
void Gui_Modal_Window::render() {

    if (!hidden) {
        // draw the gui element..
    }

}

Editor.h (摘录)

#pragma once
#include "settings.h"
#include "Layer.h"
#include "EditorMenu.h"

class EditorMenu;
class Map;
class Gui;
class Gui_Modal_Window;
class Gui_Button;

class Editor {

friend class Map;

private: 
    Gui* gui;
    Gui_Modal_Window* gui_modal_window_map_saved;
Gui_Button* gui_modal_window_map_saved_button;

// ....

Editor.cpp (摘录)

Editor::Editor() {

    //this->map = new Map();
    //this->cmd = new Command();
    //this->menu = new EditorMenu(this, cmd);
this->gui = new Gui();

// ...

创建窗口

// Saves the current map into a XML file
void Editor::tool_map_save() {

    map->save(0, *this);

    this->gui_modal_window_map_saved = new Gui_Modal_Window("Map saved", "The map has been saved."
        "This is also a very long text, to see"
        "if this gets calculated good enough!"
    );
    this->gui_modal_window_map_saved_button = new Gui_Button("Okay!", 20, 70, 200, 40, BUTTON_CONFIRM);
    gui_modal_window_map_saved->add_element(gui_modal_window_map_saved_button);
    gui_modal_window_map_saved_button->add_element(gui_modal_window_map_saved);

    gui_modal_window_map_saved->show();

}

并在编辑器:: update() - 方法:

// Gui events
    g_event g_ev = gui->get_event();

    if (g_ev.event_id == EVENT_CLICKED && g_ev.element == gui_modal_window_map_saved_button) {
        delete gui_modal_window_map_saved;
    }

1 个答案:

答案 0 :(得分:1)

如何分配Gui_Modal_Window以及如何释放它是没有错的。问题是你的Gui_Modal_Window需要有一个析构函数,这个析构函数必须释放它包装的底层GUI的所有资源。 (我们一无所知,因为你完全没有告诉我们他们,好像他们与这个问题无关。)