2014-04-17 6 views
0

xml에서 rapidxml을 사용하여 데이터를 읽는 구성 클래스를 만들려고합니다. 그러므로 내가 생성자의 내부 분석 개인 xml_document이 다음 wWinMain의 내부다른 클래스에서이 메서드를 호출하면 위반 읽기가 발생합니다.

class Config 
{ 
public: 
    Config(); 
    ~Config(); 
    /*returns the first found node*/ 
    xml_node<>* findNode(const char* name); 
    /*get an configuration value. It's always a char*/ 
    char* getConfigValue(const char* name); 

private: 
    rapidxml::xml_document<>* m_doc; 
}; 

//cpp 
Config::Config() 
{ 
    m_doc = new xml_document<>(); 
    rapidxml::file<> xmlFile("config.xml"); 
    m_doc->parse<0>(xmlFile.data()); 
    //LOG(getConfigValue("width")); // here it works 
} 
xml_node<>* Config::findNode(const char* name) 
{ 
    return m_doc->first_node()->first_node(name); 
} 
char* Config::getConfigValue(const char* name){ 
    return m_doc->first_node()->first_node(name)->value(); 
} 

가 나는 구성 opject를 생성하고 메소드를 호출하려고합니다.

Config* config = new Config(); 
LOG(config->findNode("width")->value()); // this does create violation reading 

하지만 Config 클래스의 생성자에 같은 줄을 입력해도 문제없이 작동합니다. 여기서 뭐가 잘못 됐어?

+0

것 같습니다 :

그래서 당신이 정말로 원하는이 같은 것입니다. – user657267

+0

'm_doc = new xml_document <>();'를 ctor에 추가하면 뭔가 변경됩니다. – BennX

+1

아마도'm_doc'은 사용하기 전에 뭔가를 지적해야합니다. – user657267

답변

2

나는 빠른 XML에 익숙하지 해요,하지만 빠른 구글 검색 나에게 말했다 :

http://rapidxml.sourceforge.net/manual.html

RapidXml이 매우 높은 분석 속도를 달성 할 수있는 원위치 파서이다 . 그 자리에서 파서는 문자열의 사본을 만들지 않는다는 것을 의미합니다. 대신, DOM 계층의 소스 텍스트에 대한 포인터를 배치합니다. 원본 텍스트

3.1 수명에서 현장 분석은 소스 텍스트가 적어도 한 문서 객체로서 사는 것을 요구한다. 소스 텍스트가 파기되면 DOM 트리의 노드 이름과 값이 모두 파괴됩니다. 또한 공백 처리, 문자 엔터티 변환 및 문자열의 제로 종료는 파싱하는 동안 소스 텍스트가 으로 수정되어야합니다 (비파괴 형 참조). 이로 인해 RapidXml에 의해 구문 분석 된 후 추가 처리를 위해 텍스트 이 쓸모 없게됩니다.

그래서 내가 그 걸릴하면 그냥 rapidxml :: 파일을 가질 수 있다는 것입니다 <> XMLFILE ("config.xml에");은 xml_document-> parse()가 xmlFile의 메모리를 직접 가리키는 트리를 생성 할 때 스택 변수가됩니다. 그래서 xmlFile은 최소한 xml_document만큼 메모리에 있어야합니다. 그렇지 않으면 잘못된 데이터가 생깁니다. 이는 xmlFile이 Config 클래스의 구성원이어야 함을 의미합니다. 또한 m_doc을 초기화하는 것을 보지 못했지만 코드를 생략 했습니까? 그렇지 않으면 더 빨리 불평해야하며 결코 작동하지 않아야합니다. 또한 포인터를 반환하는 함수가 읽기 위반을 피하기 위해 액세스하기 전에 null을 반환하지 않는지 항상 확인해야합니다. 어디서든`m_doc`를 초기화하지 않는 것처럼

class Config 
{ 
public: 
    Config(); 
    ~Config(); 
    /*returns the first found node*/ 
    xml_node<>* findNode(const char* name); 
    /*get an configuration value. It's always a char*/ 
    char* getConfigValue(const char* name); 

private: 
    rapidxml::file<> m_xmlFile; 
    rapidxml::xml_document<> m_doc; 
}; 

//cpp 
Config::Config() 
    : m_xmlFile("config.xml") 
{ 
    m_doc.parse<0>(m_xmlFile.data()); 
} 

xml_node<>* Config::findNode(const char* name) 
{ 
    if (m_doc.first_node()) 
    { 
     return m_doc.first_node()->first_node(name); 
    } 

    return 0; 
} 

char* Config::getConfigValue(const char* name) 
{ 
    if (m_doc.first_node()) 
    { 
     xml_node<>* node = m_doc.first_node()->first_node(name); 
     if (node) 
     { 
      return node->value(); 
     } 
    } 

    return 0; 
} 
+0

작은 오타가 있습니다. 'rapidxml :: file <> m_xmlFile;'헤더 안에 있어야합니다. 고마워요! – BennX

+0

그래, 고쳤어. 늦었 어. 자러 가야 해. << – Malketh