Ive been programming Qt for a while now and I am wondering what the difference is between these two cases:
case1:
header:
QPushButton * button;
source file:
button = new QPushButton(this);
button->setText("Button");
button->resize(100,100);
and
case2:
header:
QPushButton button;
source:
button.setParent(this);
button.setText("Button");
button.resize(100,100);
Both produce a button, but when should I use the former and when the latter case? And what is the difference between the two?
The difference between the first and second case is that when you use pointers and the new statement to allocate the button, the memory for the button is allocated in the free store (heap). In the second statement the memory is allocated on the stack.
There are two reasons why you would rather allocate memory in the free store than the stack.
The stack is of limited size and if you blow your stack budget your program will crash with a stack overflow. One can allocate much more memory in the free store and if a memory allocation fails, all that normally happens is that a bad_alloc exception is thrown.
Allocation on the stack is strictly last in first out (LIFO) which means that your button cannot exist for longer than the code block (whats between the {...} ) that allocated the memory. When memory is allocated in the free store, you as the programmer have full control of the time that the memory remains valid (although carelessness can cause memory leaks)
In your case, if the button just needs to exist for the duration of the calling function, you will probably be ok allocating the button on the stack; if the button needs to be valid for much longer stick to the free store
Qt memory management works with hierarchies of objects, when parent object deletes child objects automatically on destroying. This is why Qt programs always use pointers in similar cases.
Memory Management with Qt:
Qt maintains hierarchies of objects. For widgets (visible elements) these hierarchies represent the stacking order of the widgets themselves, for non-widgets they merely express "ownership" of objects. Qt deletes child objects together with their parent object.
In the first case you are dynamically allocating the button (which means that it will be destroyed when the parent is destroyed). In the second case the button will disappear when the code block ends (meaning it goes out of scope).
Use the first when you want to QObject, you are referring to, to last more than just the block in which it is created.
In the context of the class you are referring to (assuming the button is a member variable in both cases) it doesn't make much difference.
Also you may want to use pointers when using polymorphism.
An useful specific usage: when posting custom events, carrying detailed data, for instance:
/** support SWI... prolog_edit:edit_source(File) */
struct reqEditSource : public QEvent {
QString file;
QByteArray geometry;
reqEditSource(QString file, QByteArray geometry = QByteArray())
: QEvent(Type(User+1)), file(file), geometry(geometry) {}
};
you can 'fire and forget' them:
qApp->postEvent(this, new reqEditSource(files[i], p.value(k).toByteArray()));
The event will be deleted after its delivery.
Many functions in Qt that take an object as argument, actually take a pointer to an object. That's because passing an object "by value" would actually create a copy of the object (via copy constructor) and pass that copy! Creating a new copy of the object has a lot of overhead. At the same time, passing the object "by reference", i.e. as a pointer, will just pass a 32-Bit memory address, which is a very lightweight operation.
Related
Are there any kind of problem if I allocate QObjects on the stack to avoid problem about memory management? Should I prefer dynamic allocated QObjects and delegate memory managament by qt object trees and its ownership mechanism?
Unless it is at the very top level (in main when you create your inital window for example), you really shouldn't.
The basic reason is that Qt is simply not designed for automatic objects. Qt is designed around dynamic allocation and managing your memory for you, violating this can lead to some nasty results. One that immediatly springs to mind is the order of destruction for automatic objects, automatic objects are destructed in reverse order of their construction. So what happens in a situation like this?
...
QLabel lbl("Hello world");
QWidget win;
lbl.setParent(&win);
...
The answer is not pretty. When these objects are destructed, win will be destructed first and it will call the destructor of lbl, unfortunatly lbl is an automatic object (which means deleting it manually is undefined behaviour); it will be properly destructed after win but by that time its too late. This is just one example but it highlights some of the weird bugs which can occure if you violate Qt's assumption that it manages your memory for you.
Overall the minimal overhead of dynamic memory allocation compared to automatic allocation is worth it in order to prevent hard to track down and weird bugs like the one above. IMO you should always let Qt manage your memory for you because thats the way it was designed and thats the way it assumes you will use it.
I'm trying to translate some projects I've made with Delphi; an object can be declared in general as:
//I have the control of the object and I MUST delete it when it's not needed anymore
male := THuman.Create();
try
// code
finally
male.Free; (get rid of the object)
end;
Reading Stroustrup's book about C++ I have understood that (in short) his language doesn't need the finally block because there are always workarounds. Now if I want to create a class I have two ways:
THuman male; in which the object is created and then goes out of scope when the block {... code ...} ends
THuman* male = new THuman I can control the object's life and destroy it with a delete
The book suggests to use the first approach (even if both are fine) but I come from a Delphi background and I want to use the second method (I have the control of the object).
Questions. I cannot understand the difference between the 2 methods that C++ have for objects and reading online I got more confusion. Is it correct if I say that method 1 allocates memory on the stack and method 2 on the heap?
In method 2 (we're in the heap) if I assigned the value NULL to the object, do I still have to call the delete?
For example Delphi allows to create instances only on the heap and the Free deletes the object (like delete in C++).
In Short
1- Objects not created with new have automatic lifetime (created in the stack as you say, but that is an implementation technique chosen by most compilers), they are automatically freed once they go out of scope.
2- The lifetime of objects created with new (created in the heap, again as an implementation technique of most compilers), need to be managed by the programmer. Notice that deleting is NOT setting the pointer to NULL, it should happen before. The simple rule is:
Each new must be matched with one an only one delete
each new[] (creation of dynamic arrays) must be matched with one an only one delete[]
p.s: matched here concerns one-vs-one occurrence in the program's runtime, not necessarily in the code itself (you have control over when and where to delete any newed object).
Is it correct if I say that method 1 allocates memory on the stack and method 2 on the heap?
Yes
In method 2 (we're in the heap) if I assigned the value NULL to the object, do I still have to call the delete?
Consider using smartpointers instead of raw pointers. Smartpointers are objects which handle pointer resources and make them more safe to use.
However, if you cannot use smart pointers, make sure to call delete on the pointer to release the previous allocated memory from the heap before you assign NULL to it. Otherwise you will have leaked resources. To check your program memory management you can run valgrind
In method 2 (we're in the heap) if I assigned the value NULL to the object, do I still have to call the delete?
if you do this before calling delete you leaked memory and if you call delete on a NULL pointer you get a seg fault(application crash).
the best way is to use stack objects, but if you need to manage object's existence use smart pointer(unique_ptr, shared_ptr) as suggested above.
Note : by "Leaked memory" I mean that this region is lost it cannot be accessed from program , nor freed by OS.
I have a program (written in c++ using Qt) which shows an image in a window and takes measurements and draws to the image. All of the Qt tutorials use the heap to store user interface objects so I have done the same.
When I extend the QMainWindow class, I add a number of member variables which I use to store measurements and different versions of the image. I do not explicitly store these on the heap (no new identifier), but my understanding is if the class is defined on the heap, then so are its members.
Questions:
If the class instance is defined with new
Should the UI elements be pointers and defined with 'new' or should they just be variables and used right away? (Perhaps because UI objects can be created with parents, this makes cleanup easy.)
If they should be assigned with new in the above question, should all member variables (measurements and images) also be used with new and then deleted?
Hopefully my vocabulary is correct.
It does not matter whether UI objects will be allocated dynamically, or reside on the stack (yes, if the whole object is allocated on the heap, so are its members, but again, it does not matter whether they're pointers or not - on the other hand, performance might be worse with pointers - additional space, allocation).
In both cases, you don't have to care about resource management. That however, is not the case with your own types not deriving from QObject and not having the window as a parent. You want to avoid raw or smart pointers, where you don't need them.
I was reading through the wxWidgets tutorial: http://docs.wxwidgets.org/trunk/overview_helloworld.html
And I noticed that they use new without delete. How is this possible :S How can you use new on a class without deleting it :S It doesn't make any sense to me :l
Can someone explain what's going on?
At the end of a program's execution, all memory in the process' memory space is freed by the OS.
It is likely that the tutorial showed you a simple example that requires the instantiated objects live until the end of the program.
For example, creating the window for the program will live until the program exits. So it is not necessary to delete this since the OS will do it for you.
I am not saying this is good practice, I always suggest that you explicitly take care of freeing memory to get in good habits.
There are other options in c++, such as smart pointers, which handle deletion of objects when refcounts reach 0, but I don't think that is what is happening here.
Some class libraries have a rule which gives the ownership of pointers as children to a parent object.
In this case, when you new an object and pass it to an owner object, it is the task of the owner to delete the pointer.
For example, a widget object adds GUI controls in its children-list, when the owner is going to be deleted, its destructor delete the children.
Read the documentation of wxWidgets about avoiding memory leaks:
Child windows
When a wxWindow is destroyed, it automatically deletes all its
children. These children are all the objects that received the window
as the parent-argument in their constructors.
As a consequence, if you're creating a derived class that contains
child windows, you should use a pointer to the child windows instead
of the objects themself as members of the main window.
You CAN use New without Delete, but only if you want the lifetime of the object to last until the program exits. Generally, it IS considered bad form.
Yes, it's possible to use new without calling delete but in general it's bad form. However just because you call new without explicitly calling delete yourself does not mean it is not called. In regards to GUI frameworks many of them handle calling delete internally based on external events. For instance if you call new to create an object that represents a window the GUI framework may call delete when the OS destroys the window. It may not be obvious unless you are familiar with the framework or read the documentation for it.
There are also "smart pointers" which are objects that hold a pointer to a particular resource and release (delete) it when the smart pointer itself is destroyed. Boost and C++11 provide implementations of smart pointers (std::unique_ptr for instance) which are used quite often to manage the lifetime (and ownership) of objects created using new. This of course is a generalization of smart pointers as there are various implementations that use reference counting or other mechanisms to ensure that the resource is released only when it is no longer used.
There are many articles floating around the web concerning smart pointers, resource lifetime, resource ownership, etc. A quick Stackoverflow or Google Dance for "C++ smart pointers" will give you a vary large list of resources for further reading. Searching for the acronyms RAII and SBRM will also bring up a large list of resources.
This has got to do with the way the wxFrame class is implemented. The object will be deleted when the frame is closed.
Quoting the wxWidgets documentation:
The default close event handler for wxFrame destroys the frame using Destroy().
Typically you do need to delete objects you allocate with the new, but in this case someone else is doing it for you.
If I try and define a GUI button CButton like CButton btn; I get an error-> because I tried putting it on the stack
But if I do CButton *btn = new CButton(); It works and this is put on the heap.
Why can't I put CButton objects on the stack?
There is a common idiom in MFC which I haven't seen anywhere else. It is possible to create a "temporary" object which will be cleaned up automatically. The cleanup occurs during certain stages of MFC processing, such as the message loop.
CButton * btn = (CButton *) FromHandle(hwnd);
The FromHandle function returns a pointer to a CWnd object, but you don't know where that object came from. You should not try to delete the pointer, and don't rely on the pointer being valid beyond the current scope - never save it to a member variable! MFC will delete the object if necessary.
It is an issue of storage duration. Using MFC, the purpose of a CButton is so the user can click it, which generates an event, which you can then handle. All of this indicates that the lifetime of the CButton must extend beyond the lifetime of the function that creates it. In a typical MFC dialog class (CDialog), a CButton is a member variable, so its lifetime is the lifetime of the class instance. If you instead declare the CButton variable in the constructor it will go out of scope and be destroyed when the constructor ends.
There are some unusual situations where you might want to create buttons based on a decision not known until run-time. In that case, the above comment about not using a naked "new" is important. Use a smart pointer (or a container of smart pointers) to hold the CButton* you create, so they will be cleaned up automatically. Those smart pointers, or the container, would need to be created at class scope.
I don't know MFC, but my guess is, that your CButton, which is allocated on the stack runs out of scope, thus being destroyed.
Accessing this instance of the button from somewhere else will then cause an access violation.
1) As many others have replied, it has to do with the scope of the variable. By making it local to a function, it ends its life when the function exits.
2) Stack space is much more limited than heap space, especially with multiple threads. A typical win32 process has less than a megabyte of stack allocation, but can have thousands of megabytes of heap.