Re: Qt layout memory issue
You're creating textWidget on the stack, so probably gets deleted.
Do it as in the first case. Why does it bother you.
Actually, you also have a problem in Clear function: you make the widget null, although you should let its parent delete it. It gets reparented when you add it to a layout.
Also, I think the biggest problem is mWidget=NULL; You cannot do this with something that is allocated on the stack.
Regards
Re: Qt layout memory issue
Thanks marcel,
Actually mWidget is a pointer on the widget.
Assigning it to NULL doesn't change a thing.
another example :
This works :
Code:
ZeTextWidget * textWidget = new ZeTextWidget("Salut");
layout->addWidget(textWidget);
delete layout;
delete textWidget;
This one crashes :
Code:
ZeTextWidget textWidget("Salut");
layout->addWidget(&textWidget);
delete layout;
Thos two pieces of code are all the same for me.
- In one case :
- I'm declaring a self allowed variable in local
- Assigning it to the layout.
- Deleting the layout
- the self allowed variable is/should be deleted at the end of the function locally.
- In another case :
- I'm declaring a pointer variable
- Allocating it myself.
- Assigning it to the layout.
- Deleting the layout
- Deleting the pointer manually.
Imho the result is/should be exactly the same.
Re: Qt layout memory issue
Did you check WHERE the crash occurs? Run your code under gdb and see if the backtrace indicates that Qt code is faulty or if the error comes from yours...
Re: Qt layout memory issue
Once again I am telling you, although it it is common knowledge: you can't play with pointers like that. Take the follwoing example and test it:
Code:
void deletePtr(int* x)
{
delete x;
x = NULL;
}
int main(void)
{
int varAllocatedOnStack = 5;
deletePtr(&varAllocatedOnStack);
}
This will cause a segfault/mem violation. You can't actually delete something you allocated on the stack.
That is what is happening in your examples. If you take a closer look at how widget parent/child relations work, you will see that.
Regards
Re: Qt layout memory issue
There are only a few acceptable situations when it's ok to allocate a widget on the stack:
- a top level window in main() (since QApp::exec() blocks)
- a modal dialog anywhere (since its exec() blocks)
- perhaps some other I didn't think of
Otherwise you should likely NEVER allocate a widget on the stack. This only causes problems because a QObject automatically deletes its children. This leads to a double free attempt; 1) by parent 2) when going out of scope => crash.
Re: Qt layout memory issue
Hi!
You wrote:
Quote:
Originally Posted by
bunjee
This works :
Code:
ZeTextWidget * textWidget = new ZeTextWidget("Salut");
layout->addWidget(textWidget);
delete layout;
delete textWidget;
This one crashes :
Code:
ZeTextWidget textWidget("Salut");
layout->addWidget(&textWidget);
delete layout;
Thos two pieces of code are all the same for me.
[...]
Imho the result is/should be exactly the same.
You are partially right: the 2 pieces of code are _almost_ the same (at least for a little code like this).
In fact both works perfectly! I don't know how your second code could crash...
Can you recheck it please? May be there is something wrong with your compiler/Qt version/O.S./...?
I've checked with Qt 4.3.1 and Linux 2.6.18: no crashes at all!
Re: Qt layout memory issue
I made some tests and it seems that a child widget is automatically deleted by the destructor only by other widgets.
QLayout is not QWidget, so when you delete the QLayout, the child QWidgets are not deleted.
This is right because if you add a QWidget to a QLayout, the parent() of the QWidget is not QLayout, but equals to QLayout->parent().
Re: Qt layout memory issue
Anyway, as already said by others, don't mix stack and heap variables like that! It's very dangerous!
Sample of crashing code:
Code:
layout->addWidget(&textWidget);
groupBox->setLayout(layout);
qDebug() << textWidget.parent(); // => groupBox
delete groupBox;
Just before the crash, you see that textWidget.parent() is groupBox, so it's destructor deletes textWidget too, but textWidget is on the stack and the application crashes.
Warning that also a wrong delete can give the same result, also if everything is in the heap!
Sample of crashing code:
Code:
layout->addWidget(textWidget);
groupBox->setLayout(layout);
qDebug() << textWidget->parent(); // => groupBox
delete groupBox;
delete textWidget;
This code, instead, is not crashing!
Code:
layout->addWidget(textWidget);
qDebug() << textWidget->parent(); // => NULL
groupBox->setLayout(layout);
qDebug() << textWidget->parent(); // => groupBox
layout->removeWidget(textWidget);
qDebug() << textWidget->parent(); // => groupBox
delete groupBox;
See the comments for the output of qDebug(). Note how QHBoxLayout (add and remove functions) does not change the parent of textWidget.
In case of doubt, there is a simple rule: use only objects in the heap and store their pointers with a QPointer (it's always better to understand what you are doing, but this may help if you can't find what is crashing or if you have a shared object):
Code:
layout->addWidget(textWidget);
groupBox->setLayout(layout);
qDebug() << textWidget->parent(); // => groupBox
delete groupBox; // this deletes textWidget and sets the QPointer to NULL
delete textWidget; // textWidget now is NULL so no crash
A QPointer becomes NULL when it's object is deleted (works only with QObjects).
And remember you don't need to write code like this:
Code:
if (ptr != 0) delete ptr;
because
is valid code!
Re: Qt layout memory issue
Thanks everybody,
Well well,
The problem was coming from my side :
this :
Code:
ZeTextWidget * textWidget = new ZeTextWidget("Salut");
layout->addWidget(textWidget);
delete layout;
delete textWidget;
and this :
Code:
ZeTextWidget textWidget("Salut");
layout->addWidget(&textWidget);
delete layout;
Perfectly works.
When deleted, a layout doesn't delete the assigned objects.
Concerning the setting the pointer to NULL :
As marcel said, this doesn't work :
Code:
void deletePtr(int* x)
{
delete x;
x = NULL;.
}
int main(void)
{
int varAllocatedOnStack = 5;
deletePtr(&varAllocatedOnStack);
}
But I'm more doing something like that :
Code:
void deletePtr(int* x)
{
delete x;
}
int main(void)
{
int * newVar = new int(5);
int * newPtr = newVar;
(...)
newPtr = NULL;.
deletePtr(varAllocatedOnStack);
}
As iw2nhl said setting a pointer to NULL is a valid code.
Setting a pointer to NULL is a way knowing if a pointer has been assigned to something or not.
And correct me if I'm wrong but the heap will never create a 0 pointer variable.
Setting a pointer to NULL is like saying : okay the adress of my pointer isn't valid anymore.
And I don't see why it would crash anything in my case, and it doesn't.