PDA

View Full Version : UI and dynamic memory allocation, use of parent and child



mumbles
6th February 2013, 01:40
Hey There,

This might be more of a general C++ question so apologies in advanced if it is.

I don't have a problem with my code working, but I am just wondering about memory leaking. In my code below I declare both *sym and *myPlotMarker into dynamic memory, so when my setupgraph has finished the symbols and plotmarkers are not deleted.

1. Since I loose scope of the variable sym, this is classified as a memory leak correct?
2. Is there a way I can use parent / child with these type of dynamic definitions so this "memory leak" doesn't occur? I cannot delete the *sym pointer as if I do it within scope, then it becomes irrelevant, and I can't do it in my mainWindow class destructor as it is out of scope.




void myMainWindow::setupGraph()
{
//sets up the graph with the size of the windows.

double min_axis= -100;
double max_axis= 100;
double step_axis = 100;
int y_axis_id = 0;
int x_axis_id = 2;

ui->plotDisplayWiiOutput->autoRefresh();
ui->plotDisplayWiiOutput->autoReplot();
ui->plotDisplayWiiOutput->setAxisScale(y_axis_id,min_axis,max_axis,step_axis );
ui->plotDisplayWiiOutput->setAxisScale(x_axis_id,min_axis,max_axis,step_axis );
ui->plotDisplayWiiOutput->replot();

QwtSymbol *sym = new QwtSymbol;
sym->setStyle(QwtSymbol::XCross);
sym->setSize(20);

myPlotMarker = new QwtPlotMarker;
myPlotMarker->setSymbol(sym);

}


I have this type of declaration right through my program so I am concerned that the memory leak might cause problems at some point. Here is another instance, if I try and delete the item before I close my popup window it would be pointless.




for (i=0; i< NumberOfBins; i++)
{
QTableWidgetItem *mWidItem = new QTableWidgetItem(QString("%1 to %2 HZ")
.arg(integratedFFT[i].interval.minValue())
.arg(integratedFFT[i].interval.maxValue()));
myTableWidget->setItem(i,0,mWidItem);
}



So how do people handle this scenario. Do they globally initiate their pointers (in the header) like myPlotMarker in my example and clean them up manually in the destructor at the end of the program/object use. Or just not worry about it as all modern operating systems clean up the memory when the program exists?

Thanks for your help in advance.

Lykurg
6th February 2013, 06:43
As for the QTableWidget: It the documentation for QTableWidget::setItem() it is said that "The table takes ownership of the item.". That means when you delete the table widget, it will automatically delete all item. So no memory leak. I guess it is the same with QwtPlotMarker. See also the documentation about parent/child relations of QObject classes. Qt will delete the children automatically.

wysota
6th February 2013, 10:08
If you have doubts such as this, it is always easiest to subclass the class, reimplement the destructor and output some message there. Then you can check yourself when the destructor is called if at all. Of course instead of that you can just set a breakpoint in the destructor of the original class.

mumbles
6th February 2013, 22:26
Thanks for your help guys,

@Lykurg, the QwtPlotMarker reference materials states "The QwtPlotMarker::setSymbol() member assigns a symbol to the marker. The symbol is drawn at the specified point." so I assume that means now the plotmarker is the parent/owns the symbol and so when the marker is destroyed, it has a flow on effect to the symbol. I get a bit confused with the assigning/owning/parent terminology. I declared myPlotMarker in the header file so it has the scope of the entire class, hence I deleted it in the destructor. Reading through your reference material of QObjects, I will go through and look at QObject::findChildren & QObject::parent to make sure this parent/child relationship is occurring.

It seems as though a lot of my dynamically declared pointers are used by "parent/master" classes, so I think I have a lot less problems with deleting them than I originally thought.

@wysota, had a look into subclassing (same as inheriting in my mind). Do you mean create a dummy class with the only difference between that and the original class being the extra destructor message. Thanks for that suggestion.

Q1) It seems I intend to not destroy the majority of my dynamically pointed objects until the program finishes. And what I read is that on all modern OS that memory is reclaimed any way. So is all this memory leak stuff more of a best practice rather than an actual problem?

Q2) Does QT creator have any warning/error messages to detect memory leakage, or an automated way I can monitor this (I guess an alternative to your suggestion @wysota).

Again, thanks for your help team.

ChrisW67
7th February 2013, 01:49
Qt and the C++ STL provide smart pointer (http://en.wikipedia.org/wiki/Smart_pointer) classes for handling heap-allocated items that are not otherwise tracked. QSharedPointer is one example.

Q1. If your program only runs for short periods and does not exhaust system memory in that time then cleanup at termination is adequate but lazy. If you expect you program to continue running for days, weeks, under heavy load etc. then memory use will continue to rise until the system is exhausted of allocatable memory for the process: then bad things happen to your process and possibly others on the machine. In short, do not rely on clean up at exit; it is a bad habit to adopt.

Q2. Tools like valgrind on Linux, or any number of instrumented memory allocators (malloc() drop-in replacements).

wysota
7th February 2013, 02:05
@Q1: Also there is the aspect of maintenance. If at some day your current application grows and becomes just a part of a larger application, current laziness will require to go over the whole code looking for potential memory leaks. It is much easier to fix them as you create them than to go back and inspect the whole code after you have already forgotten what it was doing.