1

Today I was trying to find memory leaks from my project then I came across the below sample code

std::string VersionValue("1.0");
std::string EncodingValue("UTF-8");

rapidxml::xml_document<> XMLDoc;

rapidxml::xml_node<> * pHeaderNode = XMLDoc.allocate_node(rapidxml::node_declaration);
pHeaderNode->append_attribute(XMLDoc.allocate_attribute("version", VersionValue.c_str()));
pHeaderNode->append_attribute(XMLDoc.allocate_attribute("encoding", EncodingValue.c_str()));

I opened rapidxml code, inside allocate_attribute() I saw its allocating memory

xml_attribute<Ch> *attribute = new(memory) xml_attribute<Ch>;

and inside append_attribute() its assigning the memory to its member variable. There is no destructor function declared for xml_document. Then how its deleting the attributes? valgrind is returned 0 memory leaks from the above sample code. How its possible?

Gilson PJ
  • 3,443
  • 3
  • 32
  • 53

1 Answers1

1

As mentioned in comments, placement new is the answer.

This behaviour is one of the major benefits - and one of the most common gotchas - with rapidxml: It doesn't make copies of any of the data passed as parameters.

For example, if your code looked like this:-

rapidxml::xml_document<> XMLDoc;

rapidxml::xml_node<> * pHeaderNode = 
XMLDoc.allocate_node(rapidxml::node_declaration);

{
  std::string VersionValue("1.0");
  std::string EncodingValue("UTF-8");
  pHeaderNode->append_attribute(XMLDoc.allocate_attribute("version", VersionValue.c_str()));
  pHeaderNode->append_attribute(XMLDoc.allocate_attribute("encoding", EncodingValue.c_str()))
}

... then you'll usually have major problems because the attribute strings will go out of scope but rapidxml will continue to hold stale pointers to them.

Roddy
  • 66,617
  • 42
  • 165
  • 277
  • When XMLDoc goes out of the scope xapidxml will cleanup the memory pool or before going out of the score do we have to call clear() and cleanup the memory pool? Is there any way to know how much memory rapidxaml is pooling? – Gilson PJ Apr 10 '18 at 00:51
  • Stuff allocated internally by RapidXMl will of course clean up. But read the bit in the manual about "Ownership of Strings" and also "Lifetime of source text". http://rapidxml.sourceforge.net/manual.html#namespacerapidxml_1lifetime_of_source_text Because RapidXML doesn't own the "UTF-8" attribute string (in the above code) it won't delete it - and it also won't know when it's gone out of scope. – Roddy Apr 10 '18 at 09:20