mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-24 19:02:53 +00:00
118 lines
3.3 KiB
Text
118 lines
3.3 KiB
Text
![]() |
TIPS FOR CORRECT MEMORY MANAGEMENT WITH C++ AND QT
|
||
|
==================================================
|
||
|
|
||
|
|
||
|
1)
|
||
|
Use of "Smart Pointers":
|
||
|
A smart pointer in C++ means (in its most simple incarnation) a
|
||
|
pointer that automatically sets itself to 0, when the object it points
|
||
|
to is being destroyed (deleted).
|
||
|
|
||
|
Advantages:
|
||
|
|
||
|
No risk of "dangling pointers". A dangling pointer is a pointer that
|
||
|
has been deleted, but still contains the memory address of the object
|
||
|
that has been destroyed. What happens if you delete this again is
|
||
|
called a "double-free", and almost always leads to a crash. With a
|
||
|
smart pointer, you can delete the object safely again, because
|
||
|
deleting a 0-pointer is defined as a safe (doing nothing) operation in
|
||
|
the C++ standard.
|
||
|
|
||
|
Example:
|
||
|
|
||
|
WRONG:
|
||
|
|
||
|
QWidget* foo = new QWidget();
|
||
|
delete foo;
|
||
|
delete foo;
|
||
|
<BOOOOM>
|
||
|
|
||
|
RIGHT:
|
||
|
|
||
|
QPointer<QWidget> foo = new QWidget();
|
||
|
delete foo;
|
||
|
delete foo;
|
||
|
<not nice, but no crash>
|
||
|
|
||
|
|
||
|
2)
|
||
|
Always make sure not to dereference a 0-pointer:
|
||
|
|
||
|
This is _the_ single most common crash cause in Amarok 2 currently.
|
||
|
It's easy to prevent, but unfortunately also easy to miss:
|
||
|
|
||
|
Example:
|
||
|
|
||
|
WRONG:
|
||
|
|
||
|
Meta::TrackPtr foo;
|
||
|
debug() << foo->prettyUrl();
|
||
|
<BOOOOM>
|
||
|
|
||
|
RIGHT:
|
||
|
|
||
|
Meta::TrackPtr foo;
|
||
|
if( foo )
|
||
|
debug() << foo->prettyUrl();
|
||
|
<no output, and no crash>
|
||
|
|
||
|
Also be aware that Amarok is multi-threaded. So somebody could
|
||
|
change pointers while you are looking away like here:
|
||
|
|
||
|
WRONG:
|
||
|
|
||
|
Meta::TrackPtr myTrack;
|
||
|
if( myTrack && myTrack->album() )
|
||
|
debug() << myTrack->album()->name();
|
||
|
<somebody could set the album to 0 just after the if>
|
||
|
|
||
|
RIGHT:
|
||
|
|
||
|
Meta::TrackPtr myTrack;
|
||
|
Meta::AlbumPtr myAlbum = myTrack ? myTrack->album() : 0;
|
||
|
if( myAlbum )
|
||
|
debug() << myAlbum->name();
|
||
|
|
||
|
|
||
|
3)
|
||
|
Private d-pointer classes can be used in cases where the interfaces
|
||
|
of a library should remain stable but the size of members and their
|
||
|
inner working should change.
|
||
|
Qt is doing it. KDE is doing it. We are also doing it in some places
|
||
|
for no apparent reason and no benefit.
|
||
|
|
||
|
However, if you are doing it, never, ever, use private d-pointer
|
||
|
classes in QObject derived subclasses:
|
||
|
|
||
|
What can happen is that you do a "delete d;" in your destructor, and
|
||
|
then Qt goes ahead and auto-deletes other QObject pointers contained
|
||
|
in the private class again, through means of its automatic deleting of
|
||
|
QObjects with a parent Object. -> <BOOOOM>
|
||
|
|
||
|
Read more about this topic in Michael Pyne's interesting blog article:
|
||
|
|
||
|
http://www.purinchu.net/wp/2009/02/04/another-programming-tidbit/
|
||
|
|
||
|
|
||
|
4)
|
||
|
Use Valgrind:
|
||
|
<Ralf disagrees. Larger projects with big libraries will have so
|
||
|
many dirty places that Valgrind reports too many issues.
|
||
|
Our own way of handling singleton objects does not help. They
|
||
|
just leak. Instead have a sharp look at all your instance variables.
|
||
|
Ensure that all are initialized in the constructor and all deleted
|
||
|
in the destructor.>
|
||
|
|
||
|
This is one of the most advanced memory debugging tools available,
|
||
|
it's free, and we even have found volunteers that run regular Valgrind
|
||
|
checks (both for memory access bugs and memory leaks) on Amarok trunk.
|
||
|
Reading the Valgrind logs correctly is a bit of an art in itself, but
|
||
|
I'm willing to explain this in another posting, if there is a demand.
|
||
|
|
||
|
|
||
|
Recommended reading on the topic of memory management is this page of
|
||
|
the excellent "C++ FAQ Lite":
|
||
|
|
||
|
http://www.parashift.com/c++-faq-lite/freestore-mgmt.html
|
||
|
|