トップ 一覧 ソース 検索 ヘルプ RSS ログイン

Qtのメモリリークメモ

『メモリリークメモ』って変な日本語だな。それはさておき(´∀`;)

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


(2009/11/06 メモ,Qt