从其他类调用此方法会创建违规读取

问题描述 投票:0回答:1

我正在尝试创建一个配置类,它使用rapidxml从xml读取数据。因此,我有一个私有xml_document,我在构造函数内解析:

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();
}

在qazxsw poi里面我创建了一个配置对象并尝试调用这些方法。

wWinMain

但是,如果我将相同的行放入Config类的构造函数中,它可以正常工作。这里出了什么问题?

c++ class methods access-violation rapidxml
1个回答
2
投票

我不熟悉快速xml,但快速谷歌搜索告诉我:

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

RapidXml是一种原位解析器,它可以实现非常高的解析速度。原位意味着解析器不会复制字符串。相反,它将指针放在DOM层次结构中的源文本中。

3.1源文本的生命周期

原位解析要求源文本至少与文档对象一样长。如果源文本被销毁,DOM树中节点的名称和值也将被销毁。此外,空格处理,字符实体转换和字符串零终止要求在解析期间修改源文本(但请参阅非破坏性模式)。这使得文本在RapidXml解析后无法进行进一步处理。

所以我从中得到的是你不能只拥有rapidxml :: file <> xmlFile(“config.xml”);是一个堆栈变量,因为xml_document-> parse()将创建一个直接指向xmlFile内存的树。所以xmlFile必须在内存中至少与xml_document一样长,否则你将拥有无效数据。这意味着xmlFile需要是Config类的成员。另外,我没有看到你初始化m_doc,你刚刚省略了一些代码吗?否则它应该早点抱怨而且永远不会工作。此外,您应该始终检查以确保返回指针的函数在访问之前不返回null,以避免读取违规。

所以你真正想要的是这样的:

http://rapidxml.sourceforge.net/manual.html
© www.soinside.com 2019 - 2024. All rights reserved.