『メモリリークメモ』って変な日本語だな。それはさておき(´∀`;)
Qtでは、どこかのオブジェクトが破棄されるとき、子オブジェクトも破棄してくれるからメモリ管理が楽になるらしい。・・・本当にそうなのか?
明示的に破棄しないケース
テスト用のコードはこんな感じ。
01|#include <QApplication> 02|#include <QHBoxLayout> 03|#include <QLabel> 04| 05|#include "skQtLib.h" 06| 07|int main( int argc,char* argv[] ) 08|{ 09| // メモリリークを報告させる 10| 11| skDebugReport(); 12| 13| // アプリケーションクラスを作成 14| 15| QApplication app( argc,argv ); 16| 17| // ラベルをレイアウトに追加 18| 19| QHBoxLayout* lay = new QHBoxLayout(); 20| QLabel* lab = NULL; 21| 22| lab = new QLabel( "<center>left label</center>" ); 23| lay->addWidget( lab ); 24| 25| 26| lab = new QLabel( "<center>reft label</center>" ); 27| lay->addWidget( lab ); 28| 29| // メインウィンドウを作成 30| 31| QWidget* wi = new QWidget(); 32| wi->setWindowTitle( "test01a" ); 33| wi->setLayout( lay ); 34| wi->show(); 35| 36| // イベントループを回す 37| 38| return app.exec(); 39|}
ソースコードはQtのサンプルとしてありがちな形。メモリリークを報告させるために、軽く仕込みがしてあるけど本題と関係ないので省略。
これで実行すると山ほどのメモリリークがw
スレッド 'Win32 スレッド' (0xa00) はコード 0 (0x0) で終了しました。 Detected memory leaks! Dumping objects -> {14311} normal block at 0x0279C700, 252 bytes long. Data: < p > 01 00 00 00 88 DD DC 00 C8 A8 DC 00 70 A9 DC 00 {14310} normal block at 0x0279B988, 104 bytes long. Data: < > 03 00 00 00 01 00 00 00 01 00 00 00 FF FF 00 00
明示的に破棄してるケース
ソースは修正点だけ。
36| // イベントループを回す 37| 38| int rc = app.exec(); 39| 40| // メインウィンドウを破棄 41| 42| delete wi; 43| 44| return rc; 45|}
これで、メモリリークは出なくなった。ポイントはdeleteしてるのがメインウィンドウだけってこと。この時点で『QWidget → QHBoxLayout → QLabel×2』と親子関係ができてるから、QWidgetさえdeleteすれば、すべてdeleteされるってことだな。
結論
- メインウィンドウが勝手にdeleteされることはない
- 親オブジェクトを破棄すれば、子オブジェクトも破棄される
テストに使ったソースコードはこちら:test01.zip