Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-interest Archive, November 2006
crash in destructor of QBoxLayout


Message 1 in thread

Hi. I have an object which is a subclass of QDialog which has five  
QHBoxLayout objects and one QVBoxLayout object as members. Note that  
these are NOT pointers. I also have two QPushButton objects, a  
QCheckBox, two QLineEdit objects, and three QLabel objects. None are  
pointers.

In the QDialog's constructor, these objects are put together  
programatically into a layout. The various widgets are added to the  
QHBoxLayouts and then these are added to the QVBoxLayout. Finally, I  
call setLayout making the QVBoxLayout the main layout for the dialog.

When my app quits, the QDialog object gets destroyed. Its constructor  
causes an access violation. (I happen to be developing this on the  
Mac and I get a EXC_BAD_ACCESS). It tells me that this is caused by  
deallocation of a pointer that was not malloced.

I noticed that at one point, I was getting one of these error  
messages about freeing non-malloced object. Then I rearranged the  
order of the layouts in the class declaration, putting the  
QVBoxLayout after the five QHBoxLayouts. This caused me to get five  
of these messages before the crash instead of one.

The stack shows it to be crashed inside of  
QBoxLayoutPrivate::deleteAll which is called from  
QBoxLayout::~QBoxLayout which is called from the destructor of my  
QDialog subclass.

 From looking at deleteAll, it appears that it is the case that this  
method removes layout items and deletes them. Obviously my objects  
should not be deleted because they were not created with new.

Therefore, I guessed that the problem was that the QBoxLayout  
destructor calls deleteAll which deletes any items that have been  
added with addWidget or addLayout. So, I thought maybe I could remove  
these things in the destructor so that they wouldn't be there when  
delete all gets called which might cause this problem to be avoided.

So, I added code:

for (i=mHLayout0.count()-1;i>=0;--i) {
		qDebug("Remove %d\n", i);
		mHLayout0.removeItem(mHLayout0.takeAt(i));
	}
for each one of my layouts. The qDebug is there so that I could  
verify that removeItem was being called the correct number of times  
and it does appear to be the case that it is called the correct  
number of times.

I expected this to eliminate the access violation. However, it did  
not do so.

I also tried calling setLayout(NULL) on the QDialog subclass object  
inside its destructor. Still, no effect on the problem.

Any ideas on how to solve this? I could probably fix this by creating  
everything with new, but I'd prefer to understand what is going on  
and not to have to do that.

Thanks.

Brant Sears

--
 [ signature omitted ]