Results 1 to 10 of 10

Thread: Qt layout memory issue

  1. #1
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Question Qt layout memory issue

    Hello,

    I have an issue with Qt layout.

    That piece of code is working :
    Qt Code:
    1. ZeTextWidget * textWidget = new ZeTextWidget ("Salut"); // Creating a new Widget
    2. ZeTopListWidget * topListWidget1 = new ZeTopListWidget(*textWidget); // Adding the widget to the layout
    3. topListWidget1->Clear(); // Clearing the object / layout
    4. delete topListWidget1; // Deleting the object containing the layout
    To copy to clipboard, switch view to plain text mode 

    That one isn't :

    Qt Code:
    1. ZeTextWidget textWidget("Salut"); // Creating a local variable
    2. ZeTopListWidget * topListWidget1 = new ZeTopListWidget(textWidget); // Adding the widget to the layout
    3. topListWidget1->Clear(); // Clearing the object / layout
    4. delete topListWidget1; // Deleting the object containing the layout
    To copy to clipboard, switch view to plain text mode 

    When creating my "ZeTopListWidget " I'm doing this :

    Qt Code:
    1. mLayout.addWidget(&widget);
    2. mWidget = &widget;
    To copy to clipboard, switch view to plain text mode 

    When clearing my "ZeTopListWidget" I'm doing this :

    Qt Code:
    1. if (mWidget)
    2. {
    3. mLayout.removeWidget(mWidget);
    4. mWidget = NULL;
    5. }
    To copy to clipboard, switch view to plain text mode 

    When I'm:
    - Adding an allocated variable to the layout.
    - Clearing the layout (removeWidget).
    - Deleting the object containing the layout.
    -> It Works.

    BUT if I'm:

    - Adding a local variable to the layout.
    - Clearing the layout (removeWidget).
    - Deleting the object containing the layout.
    -> Crash on the delete line.

    Obviously something is going wrong when the Layout default dtor is called.
    Provided the fact that I remove the assigned widget before deleting my object and thus its member's layout: it should work fine.

    Is there something I'm missing ?
    Last edited by bunjee; 23rd August 2007 at 14:49.

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default 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
    Last edited by marcel; 23rd August 2007 at 14:59.

  3. #3
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default 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 :
    Qt Code:
    1. ZeTextWidget * textWidget = new ZeTextWidget("Salut");
    2. QHBoxLayout * layout = new QHBoxLayout();
    3. layout->addWidget(textWidget);
    4. delete layout;
    5. delete textWidget;
    To copy to clipboard, switch view to plain text mode 

    This one crashes :

    Qt Code:
    1. ZeTextWidget textWidget("Salut");
    2. QHBoxLayout * layout = new QHBoxLayout();
    3. layout->addWidget(&textWidget);
    4. delete layout;
    To copy to clipboard, switch view to plain text mode 

    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.
    Last edited by bunjee; 23rd August 2007 at 18:12.

  4. #4
    Join Date
    Jan 2006
    Location
    travelling
    Posts
    1,116
    Thanks
    8
    Thanked 127 Times in 121 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default 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...
    Current Qt projects : QCodeEdit, RotiDeCode

  5. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default 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:
    Qt Code:
    1. void deletePtr(int* x)
    2. {
    3. delete x;
    4. x = NULL;
    5. }
    6.  
    7. int main(void)
    8. {
    9. int varAllocatedOnStack = 5;
    10. deletePtr(&varAllocatedOnStack);
    11. }
    To copy to clipboard, switch view to plain text mode 

    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

  6. #6
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default 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.
    J-P Nurmi

  7. #7
    Join Date
    Jul 2007
    Posts
    35
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Qt layout memory issue

    Hi!
    You wrote:
    Quote Originally Posted by bunjee View Post
    This works :
    Qt Code:
    1. ZeTextWidget * textWidget = new ZeTextWidget("Salut");
    2. QHBoxLayout * layout = new QHBoxLayout();
    3. layout->addWidget(textWidget);
    4. delete layout;
    5. delete textWidget;
    To copy to clipboard, switch view to plain text mode 

    This one crashes :

    Qt Code:
    1. ZeTextWidget textWidget("Salut");
    2. QHBoxLayout * layout = new QHBoxLayout();
    3. layout->addWidget(&textWidget);
    4. delete layout;
    To copy to clipboard, switch view to plain text mode 

    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!
    Last edited by iw2nhl; 24th August 2007 at 00:19.

  8. #8
    Join Date
    Jul 2007
    Posts
    35
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default 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().

  9. #9
    Join Date
    Jul 2007
    Posts
    35
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default 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:
    Qt Code:
    1. QLineEdit textWidget("Salut");
    2. QHBoxLayout * layout = new QHBoxLayout();
    3. layout->addWidget(&textWidget);
    4. QGroupBox * groupBox = new QGroupBox();
    5. groupBox->setLayout(layout);
    6. qDebug() << textWidget.parent(); // => groupBox
    7. delete groupBox;
    To copy to clipboard, switch view to plain text mode 
    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:
    Qt Code:
    1. QLineEdit * textWidget = new QLineEdit("Salut");
    2. QHBoxLayout * layout = new QHBoxLayout();
    3. layout->addWidget(textWidget);
    4. QGroupBox * groupBox = new QGroupBox();
    5. groupBox->setLayout(layout);
    6. qDebug() << textWidget->parent(); // => groupBox
    7. delete groupBox;
    8. delete textWidget;
    To copy to clipboard, switch view to plain text mode 

    This code, instead, is not crashing!
    Qt Code:
    1. QLineEdit * textWidget = new QLineEdit("Salut");
    2. QHBoxLayout * layout = new QHBoxLayout();
    3. layout->addWidget(textWidget);
    4. qDebug() << textWidget->parent(); // => NULL
    5. QGroupBox * groupBox = new QGroupBox();
    6. groupBox->setLayout(layout);
    7. qDebug() << textWidget->parent(); // => groupBox
    8. layout->removeWidget(textWidget);
    9. qDebug() << textWidget->parent(); // => groupBox
    10. delete groupBox;
    To copy to clipboard, switch view to plain text mode 
    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):
    Qt Code:
    1. QPointer< QLineEdit > textWidget = new QLineEdit("Salut");
    2. QPointer< QHBoxLayout > layout = new QHBoxLayout();
    3. layout->addWidget(textWidget);
    4. QPointer< QGroupBox > groupBox = new QGroupBox();
    5. groupBox->setLayout(layout);
    6. qDebug() << textWidget->parent(); // => groupBox
    7. delete groupBox; // this deletes textWidget and sets the QPointer to NULL
    8. delete textWidget; // textWidget now is NULL so no crash
    To copy to clipboard, switch view to plain text mode 
    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:
    Qt Code:
    1. if (ptr != 0) delete ptr;
    To copy to clipboard, switch view to plain text mode 
    because
    Qt Code:
    1. delete 0
    To copy to clipboard, switch view to plain text mode 
    is valid code!

  10. The following user says thank you to iw2nhl for this useful post:

    bunjee (25th August 2007)

  11. #10
    Join Date
    Jan 2007
    Location
    Paris
    Posts
    459
    Thanks
    98
    Thanked 3 Times in 3 Posts
    Qt products
    Qt4 Qt5

    Default Re: Qt layout memory issue

    Thanks everybody,

    Well well,
    The problem was coming from my side :

    this :

    Qt Code:
    1. ZeTextWidget * textWidget = new ZeTextWidget("Salut");
    2. QHBoxLayout * layout = new QHBoxLayout();
    3. layout->addWidget(textWidget);
    4. delete layout;
    5. delete textWidget;
    To copy to clipboard, switch view to plain text mode 

    and this :

    Qt Code:
    1. ZeTextWidget textWidget("Salut");
    2. QHBoxLayout * layout = new QHBoxLayout();
    3. layout->addWidget(&textWidget);
    4. delete layout;
    To copy to clipboard, switch view to plain text mode 

    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 :

    Qt Code:
    1. void deletePtr(int* x)
    2. {
    3. delete x;
    4. x = NULL;.
    5. }
    6.  
    7. int main(void)
    8. {
    9. int varAllocatedOnStack = 5;
    10. deletePtr(&varAllocatedOnStack);
    11. }
    To copy to clipboard, switch view to plain text mode 

    But I'm more doing something like that :

    Qt Code:
    1. void deletePtr(int* x)
    2. {
    3. delete x;
    4. }
    5.  
    6. int main(void)
    7. {
    8. int * newVar = new int(5);
    9.  
    10. int * newPtr = newVar;
    11.  
    12. (...)
    13.  
    14. newPtr = NULL;.
    15.  
    16. deletePtr(varAllocatedOnStack);
    17. }
    To copy to clipboard, switch view to plain text mode 

    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.
    Last edited by bunjee; 25th August 2007 at 18:19.

Similar Threads

  1. changing layout of a widget
    By mikro in forum Qt Programming
    Replies: 10
    Last Post: 4th August 2009, 21:21
  2. Qt layout issue
    By bunjee in forum Qt Programming
    Replies: 6
    Last Post: 15th August 2007, 20:43
  3. Memory Leak in my Application :-(
    By Svaths in forum Qt Programming
    Replies: 4
    Last Post: 27th July 2007, 20:42
  4. Qt4 widget and nested layout issue.
    By bunjee in forum Qt Programming
    Replies: 12
    Last Post: 18th January 2007, 21:29
  5. "dynamic" layout
    By hulk in forum Qt Programming
    Replies: 2
    Last Post: 9th May 2006, 08:16

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.