我对以下内容不太确定:
我在头文件中创建指向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))。
我遵循了jaggedSpire的建议,用智能指针替换了所有新的/删除原始指针。而且我认为它确实改变了一些东西。查看新的附加图像 - 创建之前和关闭gui显示之后的分配数量,新分配的数量与删除的分配数量相同。我没有剖析专家 - 我在某种程度上是正确的还是这只是一个完全随意的事情?
好的,这是项目中的一些代码。我已经删除了一些我认为不必要的元素,但如果我错了,请纠正我。
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;
}
答案 0 :(得分:1)
如何分配Gui_Modal_Window
以及如何释放它是没有错的。问题是你的Gui_Modal_Window
需要有一个析构函数,这个析构函数必须释放它包装的底层GUI的所有资源。 (我们一无所知,因为你完全没有告诉我们他们,好像他们与这个问题无关。)