2

Don't understand what is going on with the attribute's memory and rapidXML. A function encapsulates the xml parsing, if success, returns a reference to the root node, when calling the traverse DOM tree inside this function I get the correct data stored in an xml file.

 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 prints all attributes and node names as expected.

Later, obviously outside the scope of Load, pRootNode will be used to query values from the DOM three, this doesn't work. For testing purposes calling TraverseDOMTree, which perfectly worked, now prints attribute's garbage values. I can assume the DOM tree is still there, the same hierarchy of nodes as in the first call, but the attributes values are messed up. I tried making the rapidxml::xml_document<> doc global and also adding the parse_non_destructive flag, none of those make a difference.

If matters, the client using the Load method is running in the same thread. What can be wrong?

Roddy
  • 63,052
  • 38
  • 156
  • 264
notNullGothik
  • 402
  • 5
  • 18

1 Answers1

3
std::vector<char> xmlCopy(bytes.begin(), bytes.end());

The local copy of the serial representation of your XML document is local. I would bet that rapidXML makes no copy of the attributes, but rather uses pointers to the sequence. You could check that by looking at the addresses of the attribute values and your document copy.

thiton
  • 34,333
  • 3
  • 63
  • 96
  • It makes perfect sense, however I did try making a persistent doc and didn't work. At least it will last until the class containing it is not destroyed, which is exactly what am doing, as far as i can understand this is correct, but there is something else wrong yet. It would be also useful to know if the doc have a clear/clean/ reset method... am checking it. – notNullGothik Dec 28 '11 at 18:03
  • This answer really saved me, thanks! I had a function that took a string and a reference to a document, and mutated the reference with the parse function. The issue was it was parsed with the local string, which promptly fell out of scope. Later on while traversing the document, it would fail indeterminately when the string was finally overwritten in memory. – Erik Uggeldahl Jun 14 '17 at 21:56