TOPページへ戻る  PCページへ戻る  一覧へ戻る

String型、動的配列のメモリリークに関して

Delphiでは、String型の変数や動的配列は基本的に自動でメモリを解放されます(プログラマがNew手続きで 意図的にメモリを確保した場合を除く)。関数や手続きを終了する際、Delphiがそれらのメモリを解放してくれるからです。 ところが、MemCheck200などを使ってメモリリークをチェックすると、 String型変数や動的配列のメモリを自動で解放しない(ようにみえる)関数があります。

この関数とはmain関数です。理由は単純で、main関数終了時(即ち、アプリ終了時)に変数のメモリを解放するため、 メモリリークをチェックしている最中(即ち、アプリ終了前)には変数のメモリが解放されないからと思われます。 そのため、main関数でString型変数や動的配列を使用し、且つメモリリークをチェックする場合、 毎回メモリリークが報告されることになります。これは鬱陶しいので、ここではString型変数や動的配列の メモリの解放の仕方について述べます。

まずは上述のメモリリークが報告される検証コードの作成から述べます。main関数は、 「ユニットの表示」メニューで表示されるユニットの中で、 プロジェクト名のユニットに書かれた関数です。例えば、新規作成で 「アプリケーション」を選択した際、次のようになっています。


program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

これにString型変数を宣言し、その変数に文字列を代入する場合、次のようになります。

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

var S : String;		// String型変数の宣言
begin
  S := 'Test';		// 適当な文字列を代入
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

MemCheck200などを使うと、このProjectが1回メモリリークしていることが判ります。 これを避けるには次のコードを追加します。


program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

var S : String;
begin
  S := 'Test';
  try
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
  finally
      S := '';		// Sに空文字を代入することでメモリが解放される
    end;
end.

String型変数は空文字を代入することでメモリが解放されます。 一方、動的配列の場合はnilを代入します。

TOPページへ戻る  PCページへ戻る  一覧へ戻る