PDA

View Full Version : QPointer and double deletion



mtrpoland
28th September 2007, 10:44
I have a

QList<QPointer<MTR::RowBox> > rowBoxes;
that is a private member of my main widget.
I want to store pointers to a few widgets in this list as well as I want to place these widgets in a gridLayout. My concern is connected to possible double deletion of these widgets as first may be done by a parent widget (received by layout) and second may be done by QList.

I receive SIGSEV for this code:


QGridLayout *qgl = new QGridLayout();
pawnBox = new MTR::PawnBox();

QPointer<MTR::RowBox> rbOne = new MTR::RowBox();
rowBoxes.push_back(rbOne);
QPointer<MTR::RowBox> rb2 = new MTR::RowBox();
rowBoxes.push_back(rb2);
QPointer<MTR::RowBox> rb3 = new MTR::RowBox();
rowBoxes.push_back(rb3);

QWidget *w1 = new QWidget();
w1->setFixedSize(50,50);
qgl->addWidget(w1,0,0,1,2);
qgl->addWidget(rbOne,1,0);
qgl->addWidget(pawnBox,1,1,3,1);
qgl->addWidget(rb2,2,0);
qgl->addWidget(rb3,3,0);
gameScreen->setLayout(qgl);

where MTR::RowBox is a pure subclass of a QWidget.

Backtrace is obvious:

#0 0x080559d6 in QList<QPointer<MTR::RowBox> >::~QList ()
#1 0x08052eb7 in MyWidget::~MyWidget ()
#2 0x0804e89e in main ()


A quotation from QPointer class documentation:

Guarded pointers are useful whenever you need to store a pointer to a QObject that is owned by someone else, and therefore might be destroyed while you still hold a reference to it.

wysota
28th September 2007, 11:06
Did you reimplement the destructor? And why do you use QPointer here in the first place? Based on the code you pasted, you don't need it.

mtrpoland
28th September 2007, 11:23
Did you reimplement the destructor?

MyWidget::~MyWidget() {
QVariant var(packRecords(rekordyLokalne));
settings->setValue("rekordyLokalne",var);
settings->sync();
file.close();
delete settings;
}


And why do you use QPointer here in the first place?
What do you mean by "here in the first place"?

wysota
28th September 2007, 11:37
It's an English idiom (something like "from the beginning", "upfront"). Why do you use QPointer?

mtrpoland
28th September 2007, 11:53
As I believe that when my MTR::RowBox'es get deleted the QPointers that are kept in the QList will be set to 0. Thus I hope that QList destructor takes it into account.

Anyway I want to keep pointers (no matter whether smart or normal) to MTR::RowBox'es in a QList and use "for" loop in order to place them in a QGridLayout.
But here comes the issue of automatical deletion of child widgets. I understand that after my actions described above each MTR::RowBox object is a child of QList and MyWidget.

How to do it safely?

wysota
28th September 2007, 12:05
But QList destructor doesn't delete pointers it holds. It only deletes objects it holds (QPointer in this case) but QPointer destructor also doesn't delete pointers it holds.

Child widgets get deleted automatically by the parent widget when the latter is destroyed.

mtrpoland
28th September 2007, 12:49
I have made some changes:

QList<MTR::RowBox *> rowBoxes;


QGridLayout *qgl = new QGridLayout();
pawnBox = new MTR::PawnBox();
for(int i=0;i<3;++i) rowBoxes.push_back(new MTR::RowBox());
qgl->addWidget(pawnBox,0,1,3,1);
for(int i=0;i<3;++i) qgl->addWidget(rowBoxes[i],i,0,1,1);
gameScreen->setLayout(qgl);

SIGSEV
Backtrace:

#0 0x08055806 in QList<MTR::RowBox*>::~QList ()
#1 0x08051b77 in MyWidget::~MyWidget ()
#2 0x0804e7ee in main ()


Could you tell me how does it happen if QList does not destroy the elements of its pointers and how to circumvent it?