Warning, /multimedia/amarok/HACKING/memory_management_tips.txt is written in an unsupported language. File is not indexed.

0001 TIPS FOR CORRECT MEMORY MANAGEMENT WITH C++ AND QT
0002 ==================================================
0003 
0004 
0005 1)
0006 Use of "Smart Pointers":
0007 A smart pointer in C++ means (in its most simple incarnation) a
0008 pointer that automatically sets itself to 0, when the object it points
0009 to is being destroyed (deleted).
0010 
0011 Advantages:
0012 
0013 No risk of "dangling pointers". A dangling pointer is a pointer that
0014 has been deleted, but still contains the memory address of the object
0015 that has been destroyed. What happens if you delete this again is
0016 called a "double-free", and almost always leads to a crash. With a
0017 smart pointer, you can delete the object safely again, because
0018 deleting a 0-pointer is defined as a safe (doing nothing) operation in
0019 the C++ standard.
0020 
0021 Example:
0022 
0023 WRONG:
0024 
0025 QWidget* foo = new QWidget();
0026 delete foo;
0027 delete foo;
0028 <BOOOOM>
0029 
0030 RIGHT:
0031 
0032 QPointer<QWidget> foo = new QWidget();
0033 delete foo;
0034 delete foo;
0035 <not nice, but no crash>
0036 
0037 
0038 2)
0039 Always make sure not to dereference a 0-pointer:
0040 
0041 This is _the_ single most common crash cause in Amarok 2 currently.
0042 It's easy to prevent, but unfortunately also easy to miss:
0043 
0044 Example:
0045 
0046 WRONG:
0047 
0048 Meta::TrackPtr foo;
0049 debug() << foo->prettyUrl();
0050 <BOOOOM>
0051 
0052 RIGHT:
0053 
0054 Meta::TrackPtr foo;
0055 if( foo )
0056    debug() << foo->prettyUrl();
0057 <no output, and no crash>
0058 
0059 Also be aware that Amarok is multi-threaded. So somebody could
0060 change pointers while you are looking away like here:
0061 
0062 WRONG:
0063 
0064 Meta::TrackPtr myTrack;
0065 if( myTrack && myTrack->album() )
0066     debug() << myTrack->album()->name();
0067 <somebody could set the album to 0 just after the if>
0068 
0069 RIGHT:
0070 
0071 Meta::TrackPtr myTrack;
0072 Meta::AlbumPtr myAlbum = myTrack ? myTrack->album() : 0;
0073 if( myAlbum )
0074     debug() << myAlbum->name();
0075 
0076 
0077 3)
0078 Private d-pointer classes can be used in cases where the interfaces
0079 of a library should remain stable but the size of members and their
0080 inner working should change.
0081 Qt is doing it. KDE is doing it. We are also doing it in some places
0082 for no apparent reason and no benefit.
0083 
0084 However, if you are doing it, never, ever, use private d-pointer
0085 classes in QObject derived subclasses:
0086 
0087 What can happen is that you do a "delete d;" in your destructor, and
0088 then Qt goes ahead and auto-deletes other QObject pointers contained
0089 in the private class again, through means of its automatic deleting of
0090 QObjects with a parent Object. -> <BOOOOM>
0091 
0092 Read more about this topic in Michael Pyne's interesting blog article:
0093 
0094 http://www.purinchu.net/wp/2009/02/04/another-programming-tidbit/
0095 
0096 
0097 4)
0098 Use Valgrind:
0099 <Ralf disagrees. Larger projects with big libraries will have so
0100 many dirty places that Valgrind reports too many issues.
0101 Our own way of handling singleton objects does not help. They
0102 just leak. Instead have a sharp look at all your instance variables.
0103 Ensure that all are initialized in the constructor and all deleted
0104 in the destructor.>
0105 
0106 This is one of the most advanced memory debugging tools available,
0107 it's free, and we even have found volunteers that run regular Valgrind
0108 checks (both for memory access bugs and memory leaks) on Amarok trunk.
0109 Reading the Valgrind logs correctly is a bit of an art in itself, but
0110 I'm willing to explain this in another posting, if there is a demand.
0111 
0112 
0113 Recommended reading on the topic of memory management is this page of
0114 the excellent "C++ FAQ Lite":
0115 
0116 http://www.parashift.com/c++-faq-lite/freestore-mgmt.html
0117