PDA

View Full Version : Widget Memory Allocation



ArlexBee-871RBO
9th May 2010, 14:33
Greetings. This is more of a C++ question, but I'm posting it here because I would like to know how it relates to Qt.

Reading books on Qt, I know that widgets should be constructed on the heap because they will be deleted automatically when their parents are deleted. My question is this: if I have a custom widget class and I instantiate it on the heap, would the members also go on the heap even though they are not dynamically created in the class?



class MyWidget : public QWidget{

private:
QPushButton myButton_;
};

...

MyWidget *w = new MyWidget;


In the example code does 'myButton_' reside on the heap or the stack? Printing the memory address it seems that it's on the heap. Does this mean that I can avoid using the 'new' operator and dynamic memory allocation for members of my class if I know for sure that the class will be constructed on the heap?

or is it always best to use pointers regardless?


class MyWidget : public QWidget{

public:
MyWidget(){
pMyButton_ = new QPushButton;
}

~MyWidget(){
delete pMyButton_;
}
private:
QPushButton *pMyButton_;
};

...

MyWidget *w = new MyWidget;

wysota
9th May 2010, 14:45
My question is this: if I have a custom widget class and I instantiate it on the heap, would the members also go on the heap even though they are not dynamically created in the class?
Yes.


In the example code does 'myButton_' reside on the heap or the stack?
It resides on the heap.

Does this mean that I can avoid using the 'new' operator and dynamic memory allocation for members of my class if I know for sure that the class will be constructed on the heap?
No. It doesn't matter whether an object resides on the heap or on the stack (you can use "new" to allocate an object in stack space as well using so called "placement new"). What matters is whether the object will be automatically destroyed or not when its "parent scope" ends. For class members their parent scope is the lifetime of the object they are contained in.


or is it always best to use pointers regardless?
In this situation you have to use a pointer for the button because otherwise it's prone to double-deletion.

Lykurg
9th May 2010, 14:49
Your pushbutton is also created on the heap. The only difference to private pointers is, that the first version needs a bigger continious space on the heap. Anyway I would suggest you to use the second variant with the pointers but also note, that your delete statement is not necessary: Just pass "this" to the c-tor of your QPushButton and it will be deleted by Qt!

Edit: too late...

ArlexBee-871RBO
9th May 2010, 17:43
Thanks for the quick reply. I do pass a parent pointer to my members, so it's all good.

For non-Qt, general C++, many have suggested that memory should be allocated on the stack whenever possible, and allocated on the heap when there is no other choice. I'm not sure if I agree with that; allocation on the stack seems to be faster, but based on my experience there is a massive performance hit if your member data are misaligned. Also, I always have the fear of encountering stack overflow.

so, what about non-widget Qt classes that don't accept parent pointers? If I have a class with many QPixmap and QBrush objects as members, is it also best to put them on the heap?

squidge
9th May 2010, 19:08
It depends on the situation. If a class can be deleted by someone who isn't the owner (eg. Widgets where the parent widget can delete them for you), then you are best with heap based storage to ensure that you don't try and delete an object which may have been already deleted.

For a 'normal' C++ class, then I prefer stack-based allocation for small objects, and heap based for objects known to be quite large. Stack based allocation is fast (one subtract on a processor register and the allocation is done), and ensures the object is deleted when it goes out of scope.

You might have guessed that I don't want the responsibility to delete objects if someone else can delete them for me.

wysota
9th May 2010, 19:51
Guys, please let's not abuse the terms "heap" and "stack". Let's call that "dynamic" and "static" allocation. If you have an object that is allocated on the heap and it has member variables (but not pointers), they will also be allocated on the heap. Also let's remember most Qt objects use the p-impl idiom, so even if you allocate such object "on the stack", most of it will actually still end up on the heap. There is no magic happening with the words "stack" and "heap" apart from that on some architectures stack memory is very limited so most objects should be allocated in the dynamic memory space (heap or global).