我决定今天将我的代码从vector
更改为unordered_map
,这样我就可以拥有字符串键值。但是,unordered_map
似乎还没有完成。
所以基本上我有一个结构类型:
typedef struct WindowData //the infamous Window Data struct
{
HWND handle;
std::unordered_map<std::string, WindowData*> children;
COLORREF color;
int height;
int width;
int x;
int y;
WindowData *parent;
bool visible;
} windowData;
然后是全局定义的实例:
WindowData MainWData = {NULL, std::unordered_map<std::string, WindowData*>(), NULL, 0, 0, 0, 0, NULL, true};
然后一个函数将一个元素添加到unordered_list
(struct member children
):
void GUI::CreateTitle(WindowData *data) //Home/About page title
{
/*...*/
WindowData wd={handle, std::unordered_map<std::string, WindowData*>(), ColorPalette.BackgroundColor, Nheight, Nwidth, x, y, data, true}; //all these values are defined within the scope of this function except ColorPalette, which is global
data->children.insert(std::make_pair("title", &wd));
}
最后,我还有其他几个函数,包括GUI类的成员和非成员,它们读取了这个元素,例如:
void GUI::CreateAboutButton(WindowData *data) //Home Page About Button
{
/*...*/
int y=data->children.at("title")->y + data->children.at("title")->height + 100;
/*...*/
}
现在,描述错误。从int y
函数中取GUI::CreateAboutButton()
。每次运行程序时,该值应该相同。通常,它类似于219.但是,现在,它每次运行程序时都会更改。有时y
是正确的值。其他时间是0.其他时候它大于40 000。
我知道这是一个内存问题,因为有时当程序运行时,它会立即发出段错误信号,当它没有时,Memory博士会显示二十多个“未初始化读取”错误。我的猜测是因为unordered_map值必须是一个结构的指针(程序不会编译,如果它只是结构值而不是指针),只要wd
的结构实例GUI::CreateTitle()
超出范围,地图仍然指向其旧的内存位置而不是实际的实例。但我不知道该怎么做(这是我第一次实现unordered_map
)是解决问题的方法。我尝试为unordered_map::insert
切换unordered_map::emplace
,但这导致了一致的段错误。
感谢任何帮助。
编辑:以下评论中的诊断/解决方案使我通过将wd
定义为班级的公共成员来解决问题。它现在工作正常,并解决了所有内存错误。
答案 0 :(得分:3)
问题在于在地图中存储指向局部变量wd
的指针。局部变量在CreateTitle
的末尾被销毁,并且地图中的指针变为悬空。一种可能的解决方案是让地图拥有孩子WindowData
,例如使用unique_ptr
:
std::unordered_map<std::string, std::unique_ptr<WindowData>> children;
然后在适当的位置创建它:
void GUI::CreateTitle(WindowData *data)
{
/*...*/
data->children.emplace(
"title",
make_unique<WindowData>(handle, std::unordered_map<std::string, std::unique_ptr<WindowData>>(), ColorPalette.BackgroundColor, Nheight, Nwidth, x, y, data, true)
);
}
添加编辑:将wd
定义为WindowData
的公共成员仅在只有一个孩子的情况下才有效。然而,拥有地图是没有意义的,不是吗?