如何从函数返回一个对象变量?

时间:2015-01-11 16:55:06

标签: c++ function return pugixml

某些变量的值正在重叠 当我第一次在一个节点上循环时,一切正常,但是当我再次循环时,会打印创建的最后一个变量的值,有时程序会停止工作。

#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时,变量值打印得很好(我认为从getNodesXML()返回值的方式有问题)

2 个答案:

答案 0 :(得分:0)

我想我解决了它:

在函数中我创建了一个pugi :: xml_document类型的对象,它是本地的,如果我创建doc对象作为指针一切正常但我想我会有内存泄漏所以我可能需要另一个返回的函数该对象稍后要删除或创建一个全局变量来存储它。

答案 1 :(得分:0)

这是在Pugi Github上记录的功能请求:

https://github.com/zeux/pugixml/issues/104

要从函数中返回对象,必须为该对象定义一个适当的副本构造函数-它可以是左值或x值副本构造函数。 pugi :: xml_document和其他pugi对象没有这样的副本构造函数,而将其包装在指针中的直觉是处理此问题的正确方法。

但是,正如您所注意到的,原始指针将为您提供一些需要解决的问题,尤其是客户端代码中潜在的内存泄漏。如果使用的是C ++ 1x,则可以通过返回智能指针(例如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);
}