C++/STL - 访问 std::map 中的类指针实例时程序崩溃

发布于 2024-09-14 14:44:17 字数 2164 浏览 0 评论 0原文

好的,我有一个函数,它读取 xml 文件并使用 new 创建控件,并将它们存储在名为 Window 的类的公共成员变量中:

std::map<const char*, Button*> Buttons;
std::map<const char*, TextBox*> TextBoxes;
std::map<const char*, CheckBox*> CheckBoxes;

Button、TextBox 和 CheckBox 类是 CreateWindowEx 的自制包装器。

这是填充地图的函数:

void Window::LoadFromXml(const char* fileName)
{
    XMLNode root = XMLNode::openFileHelper(fileName, "Window");

    for(int i = 0; i < root.nChildNode("Button"); i++)
    {           
        Buttons.insert(std::pair<const char*, Button*>(root.getChildNode("Button", i).getAttribute("Name"), new Button));
        Buttons[root.getChildNode("Button", i).getAttribute("Name")]->Init(_handle);
    }   

    for(int i = 0; i < root.nChildNode("CheckBox"); i++)
    {       
        CheckBoxes.insert(std::pair<const char*, CheckBox*>(root.getChildNode("Button", i).getAttribute("CheckBox"), new CheckBox));
        CheckBoxes[root.getChildNode("CheckBox", i).getAttribute("Name")]->Init(_handle);
    }

    for(int i = 0; i < root.nChildNode("TextBox"); i++)
    {               
        TextBoxes.insert(std::pair<const char*, TextBox*>(root.getChildNode("TextBox", i).getAttribute("Name"), new TextBox));
        TextBoxes[root.getChildNode("TextBox", i).getAttribute("Name")]->Init(_handle);
    }
}

这是 xml 文件:

<Window>
    <TextBox Name="Email" />
    <TextBox Name="Password" />

    <CheckBox Name="SaveEmail" />
    <CheckBox Name="SavePassword" />

    <Button Name="Login" />
</Window>

问题是,如果我尝试访问,例如 TextBoxes["Email"]->Width(10);,该程序编译得很好,但当我启动它时崩溃了。

我从派生类中调用它:

class LoginWindow : public Window
{
public:

    bool OnInit(void) // This function is called by Window after CreateWindowEx and a hwnd == NULL check
    {
        this->LoadFromXml("xml\\LoginWindow.xml"); // the file path is right
        this->TextBoxes["Email"]->Width(10); // Crash, if I remove this it works and all the controls are there
    }
}

Okay, I have a function which reads a xml file and creates controls using new and stores them in public member variables of a class called Window:

std::map<const char*, Button*> Buttons;
std::map<const char*, TextBox*> TextBoxes;
std::map<const char*, CheckBox*> CheckBoxes;

The Button, TextBox and CheckBox classes are homemade wrappers of CreateWindowEx.

Here is the function that populates the maps:

void Window::LoadFromXml(const char* fileName)
{
    XMLNode root = XMLNode::openFileHelper(fileName, "Window");

    for(int i = 0; i < root.nChildNode("Button"); i++)
    {           
        Buttons.insert(std::pair<const char*, Button*>(root.getChildNode("Button", i).getAttribute("Name"), new Button));
        Buttons[root.getChildNode("Button", i).getAttribute("Name")]->Init(_handle);
    }   

    for(int i = 0; i < root.nChildNode("CheckBox"); i++)
    {       
        CheckBoxes.insert(std::pair<const char*, CheckBox*>(root.getChildNode("Button", i).getAttribute("CheckBox"), new CheckBox));
        CheckBoxes[root.getChildNode("CheckBox", i).getAttribute("Name")]->Init(_handle);
    }

    for(int i = 0; i < root.nChildNode("TextBox"); i++)
    {               
        TextBoxes.insert(std::pair<const char*, TextBox*>(root.getChildNode("TextBox", i).getAttribute("Name"), new TextBox));
        TextBoxes[root.getChildNode("TextBox", i).getAttribute("Name")]->Init(_handle);
    }
}

Here is the xml file:

<Window>
    <TextBox Name="Email" />
    <TextBox Name="Password" />

    <CheckBox Name="SaveEmail" />
    <CheckBox Name="SavePassword" />

    <Button Name="Login" />
</Window>

The problem is, if I try to access, for example, TextBoxes["Email"]->Width(10);, the program compiles fine, but then crashes when I start it.

I'm calling it from a derived class:

class LoginWindow : public Window
{
public:

    bool OnInit(void) // This function is called by Window after CreateWindowEx and a hwnd == NULL check
    {
        this->LoadFromXml("xml\\LoginWindow.xml"); // the file path is right
        this->TextBoxes["Email"]->Width(10); // Crash, if I remove this it works and all the controls are there
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

燃情 2024-09-21 14:44:17

问题可能是,您的映射将 const char* 作为键 - 这并不意味着字符串,而是指针。这意味着它认为指向相同字符串的两个不同指针(例如,您的字符串文字“Email”和您从文件中读取的字符“Email”)不同,因此它找不到指向“ crash”行(并执行不存在的对象的方法)。我建议您将地图类型更改为 std::map

除此之外,我建议您使用 std::make_pair(a, b) 而不是手动指定对结构的类型。

The problem likely is, that your map has const char* as keys - and that doesn't mean strings, but pointers. Which means it sees two different pointers to the same strings (eg. your string literal "Email" and characters "Email" you've read from the file) as different, hence it doesn't find the pointer to the textbox on the "crash" line (and executes a method of a nonexistent object instead). I suggest you change your map types to std::map<std::string, ...>.

Other than that, I'd suggest you to use std::make_pair(a, b) instead of manually specifying the type of the pair structure.

无悔心 2024-09-21 14:44:17

root.getChildNode("Button", i).getAttribute("CheckBox") 返回什么?显然它是一个 char* (可能是 const),但是它分配在哪里?堆?如果是这样,什么时候释放它?

根据 API 的不同,它可能会返回一个静态缓冲区或其他不会像您的 map 持续时间那么长的东西,这可能会导致崩溃和其他奇怪的行为。您应该使您的地图看起来像这样,而不必担心它:

std::map<std::string, Button*> Buttons;
std::map<std::string, TextBox*> TextBoxes;
std::map<std::string, CheckBox*> CheckBoxes;

what do things like root.getChildNode("Button", i).getAttribute("CheckBox") return? clearly it's a char* (maybe const), but where is it allocated? Heap? If so, when do you free it?

It is possible depending on the API that it returns a static buffer or something else that doesn't last as long as your map which could lead to crashes and other funky behavior. You should make your maps look like this and not have to worry about it:

std::map<std::string, Button*> Buttons;
std::map<std::string, TextBox*> TextBoxes;
std::map<std::string, CheckBox*> CheckBoxes;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文