如何 return 函数中的对象变量?
How to return an object variable from a function?
某些变量中的值正在重叠。
当我第一次在节点上循环时,一切正常,但当我再次循环时,打印了最后创建的变量的值,有时程序停止工作。
#include "pugixml.hpp"
#include "pugixml.cpp"
pugi::xml_node varnodes = getNodesXML(varsFilepath);
for (pugi::xml_node node = varnodes.first_child(); node; node = node.next_sibling()){
printf("%s: %s\n", node.name(), node.attribute("id").value());
}
pugi::xml_node blocknodes = getNodesXML(blocksFile);
for (pugi::xml_node node = blocknodes.first_child(); node; node = node.next_sibling()){
printf("%s: %s\n", node.name(), node.attribute("id").value());
//varnodes.append_copy(node);
}
pugi::xml_node funcnodes = getNodesXML(functionsFile);
for (pugi::xml_node node = funcnodes.first_child(); node; node = node.next_sibling()){
printf("%s: %s\n", node.name(), node.attribute("id").value());
//varnodes.append_copy(node);
}
//looping on varnodes after other nodes have been created (the program crash and this is not displayed)
for (pugi::xml_node node = varnodes.first_child(); node; node = node.next_sibling())
printf("%s: %s\n", node.name(), node.attribute("id").value());
for (pugi::xml_node node = blocknodes.first_child(); node; node = node.next_sibling())
printf("%s: %s\n", node.name(), node.attribute("id").value());
for (pugi::xml_node node = funcnodes.first_child(); node; node = node.next_sibling())
printf("%s: %s\n", node.name(), node.attribute("id").value());
这是我从不同文件中获取节点的方式:
pugi::xml_node getNodesXML(char *filepath){
printf("%s\n",filepath);
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file(filepath);
if(!result) printf("Error reading file: %s\n%s\n", filepath, result.description());
pugi::xml_node nodes = doc.child("nodes");
if(!nodes) printf("Error finding root <nodes> in: \n%s\n", filepath);
return nodes;
}
xml是这样的:
varnodes.xml <nodes><node id="firstvar"></node></nodes>
blocknodes.xml <nodes><node id="firstblock"></node></nodes>
funcnodes.xml <nodes><node id="firstfunc"></node></nodes>
//Expected output:
node: firstvar
node: firstblock
node: firstfunc
node: firstvar
node: firstblock
node: firstfunc
//Wrong output Im getting (sometimes the program just stops working):
node: firstvar
node: firstblock
node: firstfunc
node: firstfunc
node: firstfunc
node: firstfunc
错误:
practice.exe 中 0x00eb0cdd 处未处理的异常:0xC0000005:访问冲突读取位置 0xfeeeff0a。
main.exe 已停止工作并向我指出此功能:
PUGI__FN xml_attribute xml_node::attribute(const char_t* name_) const
{
if (!_root) return xml_attribute();
> for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute)
if (i->name && impl::strequal(name_, i->name))
return xml_attribute(i);
return xml_attribute();
}
当我将函数中的代码添加到 main.cpp 时,变量值打印完美(我认为我 return 来自 getNodesXML() 的值的方式有问题)
我想我解决了:
在函数中我创建了一个 pugi::xml_document 类型的本地对象,如果我将 doc 对象创建为指针,一切正常,但我想我会发生内存泄漏,所以可能我需要另一个returns 稍后删除该对象或创建一个全局变量来存储它的函数。
这是关于 pugi 的记录功能请求 Github:
https://github.com/zeux/pugixml/issues/104
要return 函数中的对象,必须为该对象定义适当的复制构造函数 - 它可以是左值或 xvalue 复制构造函数。 pugi::xml_document 和其他 pugi 对象没有这样的复制构造函数,您将其包装在指针中的直觉是处理此问题的正确方法。
但是,正如您所注意到的,原始指针会给您带来一些需要应对的问题,其中最重要的是客户端代码中潜在的内存泄漏。如果您使用的是 C++1x,则可以通过 returning 智能指针解决所有这些问题,例如 unique_ptr:
#include <memory>
std::unique_ptr< pugi::xml_node> getNodesXml( char* filepath) {
// Implementation
return std::make_unique( myXmlNode);
}
并且在您的客户端代码中:
auto varNodes = getNodesXml(varsFilepath);
for (auto node = varNodes->first_child(); node; node =
node.next_sibling()){
printf("%s: %s\n", node.name(), node.attribute("id").value());
//varnodes.append_copy(node);
}
某些变量中的值正在重叠。
当我第一次在节点上循环时,一切正常,但当我再次循环时,打印了最后创建的变量的值,有时程序停止工作。
#include "pugixml.hpp"
#include "pugixml.cpp"
pugi::xml_node varnodes = getNodesXML(varsFilepath);
for (pugi::xml_node node = varnodes.first_child(); node; node = node.next_sibling()){
printf("%s: %s\n", node.name(), node.attribute("id").value());
}
pugi::xml_node blocknodes = getNodesXML(blocksFile);
for (pugi::xml_node node = blocknodes.first_child(); node; node = node.next_sibling()){
printf("%s: %s\n", node.name(), node.attribute("id").value());
//varnodes.append_copy(node);
}
pugi::xml_node funcnodes = getNodesXML(functionsFile);
for (pugi::xml_node node = funcnodes.first_child(); node; node = node.next_sibling()){
printf("%s: %s\n", node.name(), node.attribute("id").value());
//varnodes.append_copy(node);
}
//looping on varnodes after other nodes have been created (the program crash and this is not displayed)
for (pugi::xml_node node = varnodes.first_child(); node; node = node.next_sibling())
printf("%s: %s\n", node.name(), node.attribute("id").value());
for (pugi::xml_node node = blocknodes.first_child(); node; node = node.next_sibling())
printf("%s: %s\n", node.name(), node.attribute("id").value());
for (pugi::xml_node node = funcnodes.first_child(); node; node = node.next_sibling())
printf("%s: %s\n", node.name(), node.attribute("id").value());
这是我从不同文件中获取节点的方式:
pugi::xml_node getNodesXML(char *filepath){
printf("%s\n",filepath);
pugi::xml_document doc;
pugi::xml_parse_result result = doc.load_file(filepath);
if(!result) printf("Error reading file: %s\n%s\n", filepath, result.description());
pugi::xml_node nodes = doc.child("nodes");
if(!nodes) printf("Error finding root <nodes> in: \n%s\n", filepath);
return nodes;
}
xml是这样的:
varnodes.xml <nodes><node id="firstvar"></node></nodes>
blocknodes.xml <nodes><node id="firstblock"></node></nodes>
funcnodes.xml <nodes><node id="firstfunc"></node></nodes>
//Expected output:
node: firstvar
node: firstblock
node: firstfunc
node: firstvar
node: firstblock
node: firstfunc
//Wrong output Im getting (sometimes the program just stops working):
node: firstvar
node: firstblock
node: firstfunc
node: firstfunc
node: firstfunc
node: firstfunc
错误:
practice.exe 中 0x00eb0cdd 处未处理的异常:0xC0000005:访问冲突读取位置 0xfeeeff0a。
main.exe 已停止工作并向我指出此功能:
PUGI__FN xml_attribute xml_node::attribute(const char_t* name_) const
{
if (!_root) return xml_attribute();
> for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute)
if (i->name && impl::strequal(name_, i->name))
return xml_attribute(i);
return xml_attribute();
}
当我将函数中的代码添加到 main.cpp 时,变量值打印完美(我认为我 return 来自 getNodesXML() 的值的方式有问题)
我想我解决了:
在函数中我创建了一个 pugi::xml_document 类型的本地对象,如果我将 doc 对象创建为指针,一切正常,但我想我会发生内存泄漏,所以可能我需要另一个returns 稍后删除该对象或创建一个全局变量来存储它的函数。
这是关于 pugi 的记录功能请求 Github:
https://github.com/zeux/pugixml/issues/104
要return 函数中的对象,必须为该对象定义适当的复制构造函数 - 它可以是左值或 xvalue 复制构造函数。 pugi::xml_document 和其他 pugi 对象没有这样的复制构造函数,您将其包装在指针中的直觉是处理此问题的正确方法。
但是,正如您所注意到的,原始指针会给您带来一些需要应对的问题,其中最重要的是客户端代码中潜在的内存泄漏。如果您使用的是 C++1x,则可以通过 returning 智能指针解决所有这些问题,例如 unique_ptr:
#include <memory>
std::unique_ptr< pugi::xml_node> getNodesXml( char* filepath) {
// Implementation
return std::make_unique( myXmlNode);
}
并且在您的客户端代码中:
auto varNodes = getNodesXml(varsFilepath);
for (auto node = varNodes->first_child(); node; node =
node.next_sibling()){
printf("%s: %s\n", node.name(), node.attribute("id").value());
//varnodes.append_copy(node);
}