2010-08-11 1 views
2

좋아, xml 파일을 읽고 new를 사용하여 컨트롤을 만들고이를 Window :C++/STL - std :: map에서 클래스 포인터 인스턴스에 액세스 할 때 프로그램이 충돌 함

클래스의 public 멤버 변수에 저장하는 함수가 있습니다.
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 파일입니다 : 여기

는지도를 채우는 기능입니다 내가 예를 들어, TextBoxes["Email"]->Width(10);, 프로그램에 액세스하려고하면

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

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

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

문제이며, 컴파일은 잘되지만, 시작할 때 충돌이납니다.

나는 파생 클래스에서 호출 해요 :

root.getChildNode("Button", i).getAttribute("CheckBox") 반환 등의 작업을 수행 할 것을
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 
    } 
} 

답변

5

문제는 가능성이 맵이 키와 const char*을 가지고있다 : 당신은 당신의 map들과 같이 그것에 대해 걱정할 필요가 없습니다해야한다. 즉, 동일한 문자열 (예 : 문자열 리터럴 "전자 메일"및 파일에서 읽은 "전자 메일")에 대해 서로 다른 두 개의 포인터가 있다는 것을 의미합니다. 따라서 "문자열"에있는 텍스트 상자에 대한 포인터를 찾지 못합니다. 크래시 "라인 (그리고 존재하지 않는 객체의 메소드를 대신 실행합니다). 지도 유형을 std::map<std::string, ...>으로 변경하는 것이 좋습니다.

그 외에도 수동으로 쌍 구조의 유형을 지정하는 대신 std::make_pair(a, b)을 사용하는 것이 좋습니다.

+0

감사합니다. jpalecek, btw가 초급, 중급 또는 고급 질문 이었습니까? – Martin

3

? 명확하게 그것은 char* (어쩌면 const)이지만 할당 된 위치는 어디입니까? 더미? 그렇다면 언제 그것을 무료로합니까?

API에 따라 정적 버퍼 또는 map이 충돌 및 다른 펑키 동작으로 이어질 수있는 한 오래 가지 않는 다른 것을 반환 할 수 있습니다. - 그 문자열하지만, ​​포인터를 의미하지 않는다

std::map<std::string, Button*> Buttons; 
std::map<std::string, TextBox*> TextBoxes; 
std::map<std::string, CheckBox*> CheckBoxes; 
관련 문제