C ++ / STL - сбой программы при доступе к экземпляру указателя класса в std :: map - PullRequest
2 голосов
/ 12 августа 2010

Хорошо, у меня есть функция, которая читает 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
    }
}

Ответы [ 2 ]

5 голосов
/ 12 августа 2010

Вероятно, проблема в том, что ваша карта имеет const char* в качестве ключей - и это не означает строки, но указатели. Это означает, что он видит два разных указателя на одни и те же строки (например, ваш строковый литерал «Email» и символы «Email», которые вы прочитали из файла) как разные, поэтому он не находит указатель на текстовое поле на crash "(и вместо этого выполняет метод несуществующего объекта). Я предлагаю вам изменить типы карт на std::map<std::string, ...>.

Кроме этого, я бы предложил вам использовать std::make_pair(a, b) вместо указания типа структуры пары вручную.

3 голосов
/ 12 августа 2010

что возвращают вещи типа root.getChildNode("Button", i).getAttribute("CheckBox")? ясно, что это char* (может быть, const), но где он расположен? Heap? Если да, когда вы его освободите?

Возможно, в зависимости от API, он возвращает статический буфер или что-то еще, что не длится так долго, как ваш map, что может привести к сбоям и другим интересным действиям. Вы должны сделать так, чтобы ваши map выглядели так и не беспокоиться об этом:

std::map<std::string, Button*> Buttons;
std::map<std::string, TextBox*> TextBoxes;
std::map<std::string, CheckBox*> CheckBoxes;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...