Getting Started quit button example - WinXP error popup upon application exit



  • I'm a newcomer to Qt, but have used C/C++ before, and am familiarising myself with Qt using the Eclipse Indigo IDE.

    I've found an odd issue with the quit button example in the Getting Started section (i.e. http://doc.qt.nokia.com/4.7/gettingstartedqt.html ). When I run the example exactly as described in non-debug mode, and quit the application either by clicking the quit button or by clicking the top-right close icon in the window, WinXP shows the popup error "Application has encountered an error and needs to close...".

    After performing one of the above 2 quit actions while running in debug mode, the debugger shows me the error
    @warning: HEAP[QtTestApp.exe]:
    warning: Invalid Address specified to RtlFreeHeap( 003E0000, 0022FF18 )@

    After some debugging, commenting out bits of code, etc., I found that if I move the
    @QWidget window;@
    declaration to just before the
    @QTextEdit textEdit;
    QPushButton quitButton("Quit");@
    declarations, then the problem disappears.

    Can anyone tell me why this might be occurring?



  • Ok, seems you found a bug in the docs.

    A Widget destroys it's children, and the TextEdit and Button are placed on the window, so they become children.

    If you look at the "doc inside dev net, you find a doc note about it.":http://developer.qt.nokia.com/doc/qt-4.7/gettingstartedqt.html



  • So, just to confirm my understanding of how this works: even though the text editor and button controls are constructed using their default constructors (in which the parent pointer is null), adding these 2 controls to the layout object and then using this layout in the main window sets the main window to be the parent of the 2 controls?

    I also noticed in the link you provided that the updated example dynamically allocates memory for the 2 controls, whereas in my version of this example, they're both still statically allocated, but I simply moved the declaration of the main window, and this removed the WinXP error on exiting the application. What is the purpose of this dynamic memory allocation?

    Regards,

    --- Victor.


  • Moderators

    Because the parent handles the destruction of its children, you can typically only safely reparent items which have been created on the heap.

    Short version: it's bad to (in this case, indirectly) call delete on items which are on the stack.



  • Thanks for that, it makes sense :) I guess in any application with a certain number of GUI objects, you wouldn't be statically allocating them anyway, as the executable would get rather large.


  • Moderators

    It wouldn't affect the size of the executable -- the instances of the objects aren't compiled into the the executable. The app just creates them in a different chunk of memory (the stack) which has different methods and rules for handling the creation, lifespan, and deletion of objects. ("Here":http://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap is a nice brief overview.)

    Nonetheless, you are correct in the sense that in a typical "real world" app, most objects in that sense are created on the heap (with new) instead of on the stack.



  • [quote author="victor.e" date="1317852440"]So, just to confirm my understanding of how this works: even though the text editor and button controls are constructed using their default constructors (in which the parent pointer is null), adding these 2 controls to the layout object and then using this layout in the main window sets the main window to be the parent of the 2 controls?[/quote]

    Adding a widget to a layout implies reparenting them. This is to ensure lifetime and object deletion. Only top level QObjects (which have no parent and will not be part of layouts etc) should be created on the stack, all other should be on the heap.

    There are some special cases where children on the stack would work, but I would never use those.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.