メモリリーク

GCのあるC#を併用しているのでメモリリークに鈍くなってる。メモリリーク検出ツール使ってたら少し発見したので、修正。CreateしたらFreeするってのは当然として、引っかかったところ。

まず動的配列の確保と解放。

var
a: array of Integer;

begin
SetLength(a, 8); // 8要素確保

...

SetLength(a, 0); // 0をセットすることで解放
end.

あと文字列の解放。

var
a: string;
begin
a := "aaa"; // 文字列作成

...

a := "";      // これで解放される。
end.

null終端文字列ならSysUtils.StrDisposeで解放。

(2005/4/16追記)

上の例だとリークしない。メモリリーク起こる例(文字列)。

program Leak;

{$APPTYPE CONSOLE}

uses
MemCheck,
SysUtils;

const
CHARLIST: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789.-';

var
a: string;
begin
a := CHARLIST[1] + CHARLIST[2];
Writeln(a);
a := ''; // これで解放される。
end.

動的配列のほうはいまだ原因がよくわからない。SetLength(a, 0)で解決はしたんだけれども。

(2004/4/21さらに追記)

結局memcheckのバージョンが古いのが原因だったようで。memcheck 2.73は→(

http://v.mahon.free.fr/pro/freeware/memcheck/)

System.Diagnostics.Debug.Write

デバッグ用出力。

public static void Dump(byte[] b)
{
string s;
int l = 0;

System.Diagnostics.Debug.WriteLine("");
System.Diagnostics.Debug.Write("       ");
for(int i = 0; i < 16; i++)
System.Diagnostics.Debug.Write("+" + i.ToString("x") + " ");
System.Diagnostics.Debug.WriteLine("");

int cnt = ((b.Length - 1) / 16 + 1) * 16;
for(int i = 0; i < cnt; i++)
{
if(i % 16 == 0)
System.Diagnostics.Debug.Write("0x" + i.ToString("x4") + " ");

if(i < b.Length)
{
System.Diagnostics.Debug.Write(b[i].ToString("x2") + " ");
l++;
}
else
System.Diagnostics.Debug.Write("   ");
if(i % 16 == 15)
{
s = Encoding.ASCII.GetString(b, (i / 16) * 16, l);
System.Diagnostics.Debug.Write(s);
System.Diagnostics.Debug.WriteLine(" ");
l = 0;
}
}
}

/* 出力はこんな感じ
+0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f
0x0000 59 4d 53 47 00 00 00 00 00 31 00 57 00 00 00 01 YMSG
0x0010 63 36 9a 03 31 c0 80 6d 61 72 75 67 75 75 c0 80 c61@
0x0020 39 34 c0 80 44 4d 62 32 32 4d 49 38 2e 42 73 36 94@
0x0030 67 37 31 39 5a 63 31 34 54 41 2d 2d c0 80 31 33 g719Zc14TA--@
0x0040 c0 80 30 c0 80                                  @
*/

コンソールだと文字が存在しないコードもドット(.)で表示したんだけどなぁ。