I can not understand why I am getting this memory leak. First, here is the ouput from valgrind.

==27078== 24 bytes in 1 blocks are definitely lost in loss record 45 of 827
==27078==    at 0x4A061A5: operator new(unsigned long) (vg_replace_malloc.c:167)
==27078==    by 0x434B8F: ETArray::ETArray(QString const&, QWidget*) (etutils.cpp:343)
==27078==    by 0x434D4E: CheckArray::CheckArray(QString const&, QString const&, QString const&, int, int, QWidget*) (etutils.cpp:430)
==27078==    by 0x44B14F: SurfCntrlParams::SurfCntrlParams(QWidget*) (surfcntrlparams.cpp:111)
==27078==    by 0x44B7EC: SurfCntrlParams::instance() (surfcntrlparams.cpp:23)
==27078==    by 0x406F48: MetaWindow::addTab(int) (metawindow.cpp:115)
==27078==    by 0x40728E: MetaWindow::setupTabs() (metawindow.cpp:99)
==27078==    by 0x4579A0: MetaWindow::qt_metacall(QMetaObject::Call, int, void**) (moc_metawindow.cpp:69)
==27078==    by 0x58BDA7A: QMetaObject::activate(QObject*, int, int, void**) (qobject.cpp:3001)
==27078==    by 0x458D57: TramontoSim::ready() (moc_tramontosim.cpp:79)
==27078==    by 0x4209AD: TramontoSim::readyEmitter() (tramontosim.cpp:70)
==27078==    by 0x458DC1: TramontoSim::qt_metacall(QMetaObject::Call, int, void**) (moc_tramontosim.cpp:69)

This is the line that seems to be in question:

ETArray::ETArray(const QString &title, QWidget *parent)
	:ETGroupBox(title, parent)
{
	colHeadVector = new std::vector<QLabel*>(); //line 342
	rowHeadVector = new std::vector<QLabel*>(); //line 343
	widgetVector = new std::vector<std::vector<QWidget*>* >();  //line 344
	arrayGrid = new QGridLayout(); //line 345
	theGrid->addLayout(arrayGrid,1,0); //line 346
}

I don't understand why I am getting a memory leak because in the destructor I make sure to delete the vector, and all the QLabels should be deleted by QT since they all are assigned a parent widget in a different part of the program. Here's my desctructor:

ETArray::~ETArray(){
	delete colHeadVector;
	delete rowHeadVector;
	for(int i=0; i<widgetVector->size(); i++){
		delete  widgetVector->at(i);
	}
	delete widgetVector;
}

Anyone have any ideas?

Recommended Answers

All 3 Replies

colHeadVector = new std::vector<QLabel*>(); //line 342
	rowHeadVector = new std::vector<QLabel*>(); //line 343
	widgetVector = new std::vector<std::vector<QWidget*>* >();  //line 344
	arrayGrid = new QGridLayout(); //line 345

Why are those pointers? Just declare those vectors without pointers. You are not saving anything by making them pointers, instead you are creating a lot of headaches for yourself.

std::vector<QLabel*>  colHeadVector;
std::vector<QLabel*>  rowHeadVector;
std::vector< std::vector<QWidget*> >  widgetVector;

I found the problem. This is the constructor of CheckArray, a subclass of ETArray:

CheckArray::CheckArray(const QString &title, const QString &rowHead, const QString &colHead, int rows, int cols, QWidget *parent)
	:ETArray(title, parent)
{
	
	theRowHead = rowHead;
	theColHead = colHead;
	
	allCheck = new QCheckBox("Check all boxes?");
	
	colHeadVector = new std::vector<QLabel*>();
	rowHeadVector = new std::vector<QLabel*>();
	theGrid->addWidget(allCheck,0,0);
	
	changeSize(rows, cols);
	setCheckable(true);
	etResize();
}

As you can see, I called new again in here creating a second set of vectors. The first set (that I created in ETArray) must have been the ones that never got deleted. Ancient Dragon, thanks for the advice. I'm new to C++ (long time java user though), and still not quite sure when I should and shouldn't use pointers. I'm going to go back and make the change you suggested.

I'm new to C++ (long time java user though), and still not quite sure when I should and shouldn't use pointers. I'm going to go back and make the change you suggested.

Rule-of-thumb: never use pointers unless absolutely required. In your class, pointers are not needed.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.