c++rapidxml

No leaks from rapidxml


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?


Solution

  • 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.