I need a memory management lesson (XmlElements)


#1

I copyed the table class from the demo and created a filter for it in a text editor that is a child of the table. It works fine, but when I close the application it turns out I'm leaking memory. I don't want to leak memory. Thanks!

Edit: Attatched the class

//variables declared earlier
XmlElement* dataList;
XmlElement* hiddenDemoDataList;
std::vector<XmlElement*> demoDataToDelete;
std::vector<XmlElement*> hiddenDemoDataListToDelete;


void textEditorTextChanged(TextEditor& textEditorThatHasChanged)
    {
        forEachXmlChildElement(*dataList, dataListChild)
        {
            if (dataListChild != 0)
            {
                const String text(dataListChild->getStringAttribute(getAttributeNameForColumnId(2)));
  
              if (!(text.substring(0, textEditorThatHasChanged.getText().length()) == textEditorThatHasChanged.getText()) )
                {
                    if (!hiddenDemoDataList)
                    {
                        hiddenDemoDataList = new XmlElement((*dataListChild));
                    }
                    else
                    {
                        hiddenDemoDataList->addChildElement(new XmlElement((*dataListChild)));
                    }
                    hiddenDataListSize++;
                    numRows--;
                    demoDataToDelete.push_back(dataListChild);
                }
            }
        }
        for (int i = 0; i < demoDataToDelete.size(); i++)
        {
            dataList->removeChildElement(demoDataToDelete[i], true);
        }
        demoDataToDelete.clear();
        
        forEachXmlChildElement(*hiddenDemoDataList, hiddenDataListChild)
        {
            if (hiddenDataListChild != 0)
            {
                const String text(hiddenDataListChild->getStringAttribute(getAttributeNameForColumnId(2)));
                if ((text.substring(0, textEditorThatHasChanged.getText().length()) == textEditorThatHasChanged.getText()))
                {
                    if (!dataList)
                    {
                        dataList = new XmlElement((*hiddenDataListChild));
                    }
                    else
                    {
                        dataList->addChildElement(new XmlElement((*hiddenDataListChild)));
                    }
                    hiddenDataListSize--;
                    numRows++;
                    hiddenDemoDataListToDelete.push_back(hiddenDataListChild);
                }
            }
        }
        for (int i = 0; i < hiddenDemoDataListToDelete.size(); i++)
        {
            hiddenDemoDataList->removeChildElement(hiddenDemoDataListToDelete[i], true);
        }
        hiddenDemoDataListToDelete.clear();
        DemoDataSorter sorter(getAttributeNameForColumnId(2), 1);
        dataList->sortChildElements(sorter);
        table.updateContent();
        table.repaint();
    }


#2

I assume the JUCE leak detector triggered?   What type of object did it say you are leaking?

I had a look at the code and the XMLElement stuff looked okay .. that's the usual culprit here :)


#3

It’s when I close the program that it happens. I don’t know what object leaked (I see it prints somewhere, but I don’t know where to read it) but I do know one object leaked (that’s a local variable when it breaks), and when I comment out that block of code above that no objects leak.


#4

Hmm,  just guessing:

dataList and hiddenDemoDataList?

I see you instantiate them by using "new", and I don't see any "delete"...


#5


That makes sense, but it's only actually the hiddenDataList I have to delete, because dataList and demoData will mess up if you call delete on either one of them in the deconstructor (the second one will give more memory problems when the program closes (I'm assuming they are accessing the same memory)) . It's all fixed now though, thanks!