tinyxml2 icon indicating copy to clipboard operation
tinyxml2 copied to clipboard

Assertion `_attributePool.CurrentAllocs() == _attributePool.Untracked()' failed

Open terminaldweller opened this issue 8 years ago • 7 comments

I think the assert gets triggered wrongly on inheritance. I'll explain more with code: first suppose we have: in the header: BaseClass [ public: XMLReportBase(); ~XMLReportBase();

void CreateReport(void);

virtual void AddNode(void) = 0;

void SaveReport(const char*);

protected:
XMLDocument Doc;
XMLElement* RootPointer;

}

in the source file: BaseClass { XMLReportBase::XMLReportBase() { RootPointer = Doc.NewElement("mutagen:Report"); RootPointer->SetAttribute("xmlns:mutator", "http://www.w3.org/2001/XMLSchema"); }

XMLReportBase::~XMLReportBase() { Doc.InsertEndChild(RootPointer); }

void XMLReportBase::CreateReport() { Doc.InsertFirstChild(RootPointer); }

void XMLReportBase::SaveReport(const char* __filename) { Doc.InsertEndChild(RootPointer);

XMLError XMLErrorResult = Doc.SaveFile(__filename);

if (XMLErrorResult != XML_SUCCESS)
{
  std::cerr << "could not write xml misra report.\n";
}

} }

now if: B : BaseClass { /ctor,dtor,implementation of the pure virtual function, .../ }

this will trigger the assert. If I just move everything into B without inheritance then the assert won't get triggered. Am I doing something wrong or the assert is being raised incorrectly? BTW, thank you for tinyxml2. it makes life easier. :)

terminaldweller avatar May 23 '17 11:05 terminaldweller

This is most likely because of destructor of XMLReportBase not being virtual. How exactly is the object created and deleted where you observe the problem? Do you have a minimal source which shows the problem with the above two classes? Which compiler (and which version) do you use?

Dmitry-Me avatar May 23 '17 13:05 Dmitry-Me

I did try the virtual destructor, it still keeps raising the same assert. actually the above code was kinda a minimal source version of the original code. The original piece is on my repo but I guess looking at it there is gonna take more time than necessary. or i can just cut the relevant pieces and put them up here. I'm using clang, trunk 301395. I build my own. Regarding the way it's built and destructed, it's nothing fancy. I just call the constructor for B, call XMLReportBase::CreateReport and XMLReportBase::SaveReport, the assert fails even with just creating a doc, and adding a root node and then just saving it: void myclass::myfunc(void) { B b(myvar1); b.CreateReport(); b.SaveReport(); }

then I just call mycall::myfunc(). Also for the record, the XML document is just fine(I've looked at issue #129., At first I though the problem was that, but like I said I get the same assert with just adding one root node.

terminaldweller avatar May 23 '17 14:05 terminaldweller

Does the same node get added multiple times into the DOM?

Dmitry-Me avatar May 23 '17 14:05 Dmitry-Me

in the original code i have a vector<vector> being added in, but like i said, i tried it without that, it literally just adds a root node and then just saves it but i still get the same problem.

On 5/23/17, Dmitry-Me [email protected] wrote:

Does the same node get added multiple times into the DOM?

-- You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub: https://github.com/leethomason/tinyxml2/issues/555#issuecomment-303412774

-- Farzad Sadeghi project mutator-https://github.com/bloodstalker/mutator

terminaldweller avatar May 23 '17 14:05 terminaldweller

What's inside

/ctor,dtor,implementation of the pure virtual function, .../

?

Dmitry-Me avatar May 25 '17 12:05 Dmitry-Me

ctor:

RootPointer = Doc.NewElement("mutagen:Report");
RootPointer->SetAttribute("xmlns:mutator", "http://www.w3.org/2001/XMLSchema");

dtor:

Doc.InsertEndChild(RootPointer);

other stuff: in the header:

virtual void AddNode(void) = 0;

in the source: DoomedStrains is vector<vector>

virtual void AddNode(void)
    {
      XMLElement* MGene = Doc.NewElement("DoomedStrains");

      for (auto &iter : DoomedStrains)
      {
        XMLElement* NodeDoomedStrain = Doc.NewElement("DoomedStrain");

        for (auto &iterer : iter)
        {
          XMLElement* Child = Doc.NewElement("Strain");
          Child->SetText(iterer.c_str());
          NodeDoomedStrain->InsertEndChild(Child);
        }
        
        MGene->InsertEndChild(NodeDoomedStrain);
      }

      RootPointer->InsertEndChild(MGene);
    }

terminaldweller avatar May 26 '17 19:05 terminaldweller

There's good chance that for some reason you have XMLNode::InsertAfterChild() called with insertThis being equal to afterThis and that's the node other than the last one on that level.

Dmitry-Me avatar May 31 '17 16:05 Dmitry-Me