2010-11-26 7 views
7

非常に簡単な質問:ここにメモリリークがありますか?

type 

TMyRecord = Record 
    Int: Integer; 
    Str: String; 
end; 

PMyRecord = ^TMyRecord; 

var 
    Data: PMyRecord; 
begin 
    New(Data); 
    Data.Int := 42; 
    Data.Str := 'Test'; 
    Dispose(Data); 
end; 

私の質問は、私は(文字列で)ここにメモリリークを作成していますか?私はData.Strを呼び出す必要があります:= '';ディスポーザルに電話する前に?

ありがとうございます!

+0

私はそれほどそうではないと思います。 –

答えて

12

いいえ、Disposeは、ネストされたものも含めて、文字列と動的配列をレコード内で適切に解放します。 GetMem/FreeMem(Data)はメモリリークを作成します。

+3

バリエーション、リファレンスカウントされたインターフェイス、おそらく匿名関数をリストに追加すると、参照カウントされたものはすべて 'Dispose()'で解放されると思います。 – Trinidad

+2

GetMem/FreeMemはFinalize()を呼び出す必要があります。 Dispose()を使用できないときの処理の説明については、ヘルプの「Finalize」をチェックしてください。 –

+3

@ldsanson:New = GetMem +初期化とDispose = Finalize + FreeMem - System.pasを確認します。これらは両方の機能のラッパーです。 –

0

あなたはそうではありませんが、Stringは削除されたときに自身のメモリ自体を消去します。

+2

実際には、包囲構造が完成すると文字列自体が解放されます。 –

0

あなたがメモリリークをしたい場合は、私の知る限りであなたが彼らは例外がで発生した場合それはメモリリークです

+2

TPオブジェクトが初期化されます。彼らはレコードと同じように扱われます。 Delphiでは、メソッドを使ってレコードをサポートするまで、実際にそれらを広範囲に使用していました。 –

+0

レコードまたはオブジェクトは、動的配列またはスタック上でインスタンス化する場合、メモリリークを作成しません。これは非常に一般的です。ヒープ割り当てでのみNew()とDispose()が必要です。 new(aRecordPointer)をanObject.Createよりも使用するのはそれほど難しくありません... –

+0

http://groups.google.com/group/comp.lang.pascal.delphi.misc/msg/2176ea3300f2dfb9承認済みで、TPオブジェクトVMTを持つしたがって、レコードとしての使用はOKです。オブジェクトとしての使用法はありません。 –

10

を確定/初期化されていないDelphiで唯一の構造化タイプの私の知る限りです:-) TPオブジェクトを使用する必要がありますあなたの割り当て/割り当て解除のペアの間。

New(Data); 
Try 
    Data.Int := 42; 
    Data.Str := 'Test'; 
Finally 
    Dispose(Data); 
End; 
+1

+1 try ... finally –

+0

レコードを動的配列にするか、スタックに配置する方がよいでしょう。両方とも、すべてのレコード項目の内容を初期化します。 try..finallyは、TObject.Createが対応するtry..finally Freeを必要とするように、ヒープ割り当てに必須です。そのようなtry ... finallyは、レコードが動的配列またはスタックに割り当てられている場合、コンパイラによって自動的に作成されます。 –

+0

@ArnaudBouchez配列が必要な場合は配列に割り当てます。単一のレコードが必要な場合は適切ではありません。レコードのライフタイムがレコードを作成するスコープよりも長くなければならない場合は、スタックではなく、 'New'でヒープを割り当てます。 –

関連する問題