For QObjects created on the heap with no parent, I found that destructor is not called. So, I starting using the core application instance as their parent to ensure that they are cleaned by garbage collector. Is this the right action, or what should I exactly to safely de-allocated these objects?
Here is an example of what I am doing:
// Use application instance as parent to avoid memory leak if object is not deleted
m_qObject = new DataHandler(QCoreApplication::instance());
Qt doesn't have an independent memory management, such as a garbage collector. The explicit parent-child relationship used is a classic ownership model that helps in the automatization of object life-cycles, it is deterministic (it will delete object on parent's destruction), and it is very natural with user interfaces.
If an object is created (in the heap) without a parent, it will generate a memory leak when the last reference to it is lost. Objects in the stack should not have a parent to prevent double-delete errors (check Qt documentation for further information)
If you set QApplication::instance as the parent of an object, you are basically telling it not to be destroyed until the application quits. If that's the case, then there is no such a great difference with other standard memory leaks, escept the object's destructor does something else than just releasing memory (such as closing OS-wide handles, saving files, etc).
There is a very interesting case I was curious about: what happened when the original parent (Q*Application::instance) was replaced at any given moment, as in this question?
The case is that the ownership of the object is transferred from the former Q*Application instance to the new one. It may become a problem if you rely on the existence of the object through the whole application life-span but several instances of Q*Application are allowed to be created and destroyed at any moment. One scenario would be a non-Qt application loading plug-ins or components built on Qt, in where you cannot control the creation/destruction order.
If that's the case, I'd suggest to find another way to destruct your object, such as having your own singleton inheriting from QObject that you can use as parent.
Related
I am studying a book called "C++ How to Program" by Paul Deitel, chapter 9 is talking about Classes, and I quote:
The destructor itself does not actually release the object's memory--it performs termination housekeeping before the object's
memory is reclaimed, so the memory may be reused to hold new objects.
so my question is, what does the Author mean by Termination housekeeping and releasing memory? and how different they are from each other? if they are any different.
What it means is the destructor function does not release memory, but it is a place where you can declare what housekeeping functions need to be done. For example, if your object owns pointers to other data that it should release, then it's time to delete those. For example if you had a pointer named owned that was given something to retain:
MyThing::~MyThing() {
delete owned;
}
This delete call will trigger the destructor for that owned object if it has one, which initiates this process all over again in a recursive manner.
You might also close file-handles, delete temporary files, whatever it is your object should do when tidying up. That might include deleting operating-system GUI elements as well, it really depends on where this code lives.
The destructor is called during the process of releasing memory, but it itself does not release any of its own memory. That action is performed after the destructor finishes.
There are other forms of cleanup besides releasing memory. Sometimes you may need to close a communications channel during the terminator of a class. Or you might release resources used for threading when a class closes. Or maybe you just modify a pointed to object.
The destructor is the code that runs when the object falls out of scope. There's nothing else to it.
I am familiar with std::shared_ptr and std::weak_ptr and know how they work. However, I would like the std::shared_ptr to emit a callback, like a boost signal. This would allow std::weak_ptr, who still refer to the deleted object, to be cleaned up right in time.
Is there maybe already some smart pointer implementation, which will report the destruction?
Explanation
I think there might be a small design flaw in std::weak_ptrs, that can lead to false memory leaks. By "false memory leak" I mean an object, that is still accessible by the program, but whose reason of existence is not valid anymore. The difference to a true memory leak is, that the true memory leak is completely unknown by the program, while the false leak is just a part that wasn't cleaned up properly.
Another description can be found at codingwisdom.com
Use Watchers
One of the problems with freeing an object is that you may have done so while other things are still pointing at it. This introduces dangling pointers and crashes! To combat the evil of dangling pointers, I like to use a basic "watcher" system. This is not unlike the weak reference discussed above. The implementation is like this:
Create a base class "Watchable" that you derive from on objects that should broadcast when they're being deleted. The Watchable object keeps track of other objects pointing at it.
Create a "Watcher" smart pointer that, when assigned to, adds itself to the list of objects to be informed when its target goes away.
This basic technique will go a long way toward solving dangling pointer issues without sacrificing explicit control over when an object is to be destroyed.
Example
Let's say we implement the observer pattern using boost Boost Signals2. We have a class Observable, that contains one or more signals and another class Observer, that connects to Observable's signals.
What would happen to Observable's slots, when a observing Observer is deleted? When we do nothing, then the connection would point to nowhere and we would probably receive a segmentation fault, when emitting the signal.
To deal with this issue, boost's slots also offer a method track(const weak_ptr<void>& tracked_object). That means, if I call track and pass a weak_ptr to Observer, then the slot won't be called when the weak_ptr expired. Instead, it will be deleted from the signal.
Where is the problem? Let's we delete an Observer and never call a certain signal of Observable ever again. In this case, the tracked connection will also never be deleted. Next time we emit the signal it will be cleaned up. But we don't emit it. So the connection just stays there and wastes resources.
A solution would be: when owning shared_ptr should emit a signal when it is destroying it's object. This would allow other other objects to clean up right in time. Everything that has a weak_ptr to the deleted object might register a callback and false memory leaks could be avoided.
//
// create a C function that does some cleanup or reuse of the object
//
void RecycleFunction
(
MyClass * pObj
)
{
// do some cleanup with pObj
}
//
// when you create your object and assign it to a shared pointer register a cleanup function
//
std::shared_ptr<MyClass> myObj = std::shared_ptr<MyClass>( new MyClass,
RecycleFunction);
Once the last reference expires "RecyleFunction" is called with your object as parameter. I use this pattern to recycle objects and insert them back into a pool.
This would allow std::weak_ptr, who still refer to the deleted object,
to be cleaned up right in time.
Actually, they only hold weak references, which do not prevent the object from being destroyed. Holding weak_ptrs to an object does not prevent it's destruction or deletion in any fashion.
The quote you've given sounds to me like that guy just doesn't know which objects own which other objects, instead of having a proper ownership hierarchy where it's clearly defined how long everything lives.
As for boost::signals2, that's what a scoped_connection is for- i.e., you're doing it wrong.
The long and short is that there's nothing wrong with the tools in the Standard (except auto_ptr which is broken and bad and we have unique_ptr now). The problem is that you're not using them properly.
I have a QTreeView with associated QStandardItemModel and QStandardItem's that fill the model. Then i also have a slot function that connects to clicked(QModelIndex) on the model and does some stuff. While building the model i would like to pass in some custom data to the QStandardItem's so that the slot function can do something with it. I managed to get this working through the method described here.
However i'm concerned about there being a possible memory leak with this method and what to do about it. If it does leak, i cant delete it from the associated slot function since the view will still be there and the user may click the same item again (and then point to a NULL reference) and im not totally sure about possible ways to enclose the pointer with a smart pointer because of the relationship with the Q_DECLARE_METATYPE(Object*) macro and how data is set to QStandardItemto
So does this cause a memory leak without an associated delete here and if it does, what are the best ways to get around this?
If you declare a pointer as metatype, Qt will internally manage the pointer alone, so it's your responsibility to ensure that the object is deleted in due time (by deleting it manually and clearing references to it or assiging a parent to it and ensuring the parent is deleted. You can avoid memory leaks by using value-based metatype, e.g. Q_DECLARE_METATYPE(MyClass). However MyClass should have copy constructors so QObject will not do. You can also use shared pointers: Q_DECLARE_METATYPE(QSharedPointer<QObject*>). Qt will internally keep shared pointers and delete them when appropriate view items are removed, so the underlying object will be deleted if your code doesn't contain another shared pointers to it. Refer to QSharedPointer documentation to learn how to use it correctly.
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.
I've been building a system with a parent object, where it creates various child objects, and each child object requires a master object to function. Now, so far, I've been creating shared_ptr<Parent> and Child*, so when the creator of Parent and all the Childs are gone, the Parent goes too.
But I'm re-designing my API so that Child can be created on the stack (previously it was just the heap). Now I'm unsure about what to do with Parents, as I don't see why they shouldn't also be creatable on the stack- in terms of their actual function- but what happens if Parent is destroyed and then someone tries to use a Child that they moved, copied, or allocated on the heap? Should I just throw an exception? Skip performing the operation? Or just stick to allocating Parents on the heap?
Here's the problem sentence
if Parent is destroyed and then someone tries to use a Child ...
If this is possible then you have shared ownership, which implies creation on the heap.
So, either you stick to heap allocation or drop the shared ownership semantics. There is no other way. weak_ptr is merely away of advertising the state of a shared object.
If you really want to do what you're advertising:
if Parent is destroyed and then someone tries to use a Child ...
This is going to cause a problem as #spraff mentioned.
The way to achieve what you are saying is to also make the Child a shared_ptr and allow a shared ownership between the Parent and also whatever else is trying to use the child...