gpt4 book ai didi

c++ - 从其他类调用此方法会创建违规阅读

转载 作者:行者123 更新时间:2023-11-28 02:50:45 24 4
gpt4 key购买 nike

我正在尝试创建一个配置类,它使用 rapidxml 从 xml 中读取数据。因此我有一个私有(private)的 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();
}

wWinMain 内部,我创建了一个配置对象并尝试调用这些方法。

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

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

最佳答案

我不熟悉 rapid xml,但是快速的 google 搜索告诉我:

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

RapidXml is an in-situ parser, which allows it to achieve very high parsing speed. In-situ means that parser does not make copies of strings. Instead, it places pointers to the source text in the DOM hierarchy.

3.1 Lifetime Of Source Text

In-situ parsing requires that source text lives at least as long as the document object. If source text is destroyed, names and values of nodes in DOM tree will become destroyed as well. Additionally, whitespace processing, character entity translation, and zero-termination of strings require that source text be modified during parsing (but see non-destructive mode). This makes the text useless for further processing once it was parsed by RapidXml.

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

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

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

关于c++ - 从其他类调用此方法会创建违规阅读,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23126496/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com