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