【问题标题】:rapidXML, corrupted memory when traversing DOM treerapidXML,遍历 DOM 树时损坏的内存
【发布时间】:2011-12-28 17:57:15
【问题描述】:

不明白属性的内存和 rapidXML 发生了什么。 一个函数封装了xml解析,如果成功,返回一个对根节点的引用,当在这个函数内部调用遍历DOM树时,我得到正确的数据存储在一个xml文件中。

 typedef rapidxml::xml_node<>* Node;
 ...
 Node Load()
 {
     Node pRootNode = NULL;
     // read file stream in bytes
     ...
     std::vector<char> xmlCopy(bytes.begin(), bytes.end());
     xmlCopy.push_back('\0');
     rapidxml::xml_document<> doc;

    try
    {
      doc.parse<rapidxml::parse_declaration_node | rapidxml::parse_no_data_nodes>(&bytes[0]);
      pRootNode = doc.first_node();
          ...
          TraverseDOMTree(pRootNode);
    }
    return pRootNode;
 }

TraverseDOMTree 按预期打印所有属性和节点名称。

后来,很明显超出了Load的范围,pRootNode会被用来从DOM 3中查询值,这样就不行了。 出于测试目的调用 TraverseDOMTree,它完美地工作,现在打印属性的垃圾值。我可以假设 DOM 树仍然存在,与第一次调用中的节点层次结构相同,但属性值搞砸了。 我尝试将 rapidxml::xml_document doc 设为全局并添加 parse_non_破坏性 标志,但这些都没有影响。

如果重要的话,使用 Load 方法的客户端在同一个线程中运行。有什么问题?

【问题讨论】:

    标签: c++ rapidxml


    【解决方案1】:
    std::vector<char> xmlCopy(bytes.begin(), bytes.end());
    

    您的 XML 文档的串行表示的本地副本是本地的。我敢打赌 rapidXML 不会复制属性,而是使用指向序列的指针。您可以通过查看属性值的地址和您的文档副本来检查。

    【讨论】:

    • 这很有意义,但是我确实尝试制作一个持久的文档但没有奏效。至少它会持续到包含它的类没有被破坏,这正是我正在做的事情,据我所知这是正确的,但还有其他错误。了解文档是否有 clear/clean/reset 方法也很有用......正在检查它。
    • 这个答案真的救了我,谢谢!我有一个函数,它接受一个字符串和一个对文档的引用,并用 parse 函数改变了引用。问题是它是用本地字符串解析的,很快就超出了范围。稍后在遍历文档时,当字符串最终在内存中被覆盖时,它会不确定地失败。
    猜你喜欢
    • 2015-04-16
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    相关资源
    最近更新 更多