関数でTStringListを返すには


久しぶりに使います  2013-12-09 06:50:06  No: 45693

関数でTStringListを返すにはどうしたらいいんでしょうか?

関数内でできたtxt3というTStringListを返したいのですが、
Result.Assign(txt3);//エラーになります

Result:=txt3;//これだとエラーにならないんですが、メモリを開放する必要はありませんか?

TStringListを参照渡しするのが一番簡単なんでしょうか?


deldel  2013-12-09 18:19:07  No: 45694

関数内でできたTStringListを返すためには
関数内でFreeできないので、メモリリークを起こすのでは?
と思いますが・・・

//良い例?
procedure Kansuu(var sl: TStringList);
begin
  sl.Add('aaa');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  try
    Kansuu(sl);
    showmessage(sl[0]);
  finally
    sl.Free;
  end;
end;

//悪い例
procedure Kansuu2(var sl: TStringList);
begin
  sl := TStringList.Create;
  try
    sl.Add('bbb');
  finally
    //sl.Free; //これがあるとエラー。無いとメモリリーク
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  sl: TStringList;
begin
  Kansuu2(sl);
  showmessage(sl[0]);
end;


RAD命  2013-12-10 02:09:45  No: 45695

初めまして。久しぶりに書き込みます。
deldelさんの方法と似ていますが、
自分の場合、以下の方法で多用しています。
(以前に必要に迫られて以下の方法にたどり着いたのですが、
この自分の方法が正しいかどうかは判りません。)

function strlst:Tstringlist;
var
  i:integer;
begin
  strlst := TStringList.create;
  for i:= 0 to 10 do begin
    strlst.Add(inttostr(i));
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  memo1.Lines.Text := strlst.Text;
  strlst.Free;
end;


おかぽん  2013-12-10 02:27:38  No: 45696

RAD命さん
>  memo1.Lines.Text := strlst.Text;
>  strlst.Free;
Textプロパティの参照と、Freeで、二回strlst関数呼ばれていませんか?

with strlst do
  memo1.Lines.Text := Text;
  Free;
end;

とか

var
  sl: TStringList;
begin
  sl := strlst;
  memo1.Lines.Text := sl.Text;
  sl.Free;
end;

ではないかと。


RAD命  2013-12-10 03:49:04  No: 45697

>おかぽんさん

ご指摘ありがとうございます。
確かに、strlstは関数なので、
二度呼ばれることになりますね^^;

大変為になります。

前述のdeldelさんのコードを参考に、以下のようにしてみました。

function strlst(s:Tstringlist):boolean;
var
  i:integer;
begin
  try
    for i:= 0 to 10 do begin
      s.Add(inttostr(s.Count));
    end;
    strlst := true;
  except
    strlst := false;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  s:TStringlist;
  i:integer;
begin
  s := TStringList.Create;
  for i := 0 to 10 do begin
    if not strlst(s) then begin
      break;
      showmessage('エラー');
    end;
  end;
  memo1.Lines.Text := s.Text;
  s.Free;
end;


FUD命  2013-12-10 04:25:44  No: 45698

> RAD命さん

初心者は質問に答えるなとまでは言いませんけど、
自分で正しいかどうかもわかってないコードを人に薦めるのはどうなんでしょう。

それから、そのコードではShowMessageは実行されませんよ。
Breakの位置がおかしいです。あとtry finallyを使いましょう。


久しぶりに使います  2013-12-10 05:06:04  No: 45699

みなさん、回答ありがとうございます。
ところで、ちょっとスレから外れますけど、
メモリリークを起こした場合、元に戻るのは(正常になるのは)いつなんでしょうか?
1.プログラムを終了した場合
2.PCを再起動した場合
3.その他
参考までにわかる方がおられれば、答えていただけたら嬉しいです。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加