全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2626
推到 Plurk!
推到 Facebook!

副程式 TStrings 回傳與釋放

答題得分者是:herbert2
boy330077
一般會員


發表:39
回覆:59
積分:19
註冊:2009-10-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2014-09-22 10:49:31 IP:211.20.xxx.xxx 訂閱

[code delphi]
function MyFun:TStrings;
var
ts:Tstrings;
begin
ts:=TStringList.Create;

//---do something
Result:=ts;
//--- ts.free 這邊 FREE 會錯
end;

procedure TForm1.Button1Click(Sender: TObject);
var
ts:TStrings;
begin
ts:=TStringList.Create;

ts:=MyFun;
//--do something
ts.Free;
end;

[/code]


如上面
在 MyFun 裡面 FRee會錯 不Free又覺得怪怪的
本來想以 記憶體位置 檢查是否依然存在未釋放
但是對指標與記憶體不熟
想請問高手 正確方法因該如何使用
感謝指導
herbert2
尊榮會員


發表:58
回覆:632
積分:878
註冊:2004-04-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2014-09-22 11:58:26 IP:202.39.xxx.xxx 訂閱
在自訂的 MyFun 中增加一個『TStrings 位址』的參數,
接收呼叫者(CallFun)傳進呼叫者擁有的 TStrings 的 Address.
將 MyFun 的 TStrings result 填入 CallFun 的 TStrings.
將 MyFun Create 的臨時 TStrings Free 掉後 return.

若不影響其他程式, 也可以在 MyFun 中直接使用 CallFun 的 TStrings
(因為傳址, 故 Name 已變成 MyFun 接收的 Name),
那就不用 Create Private TStrings, 也就不用 Free.
編輯記錄
herbert2 重新編輯於 2014-09-22 12:00:20, 註解 無‧
boy330077
一般會員


發表:39
回覆:59
積分:19
註冊:2009-10-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2014-09-22 13:34:07 IP:211.20.xxx.xxx 訂閱
方案一
[code delphi]
function MyFun(ts:TStrings):TStrings;
var
i:integer;
begin

{$REGION 'do something'}
ts.BeginUpdate;
for i := 65 to 70 do
ts.Append(Chr(i));
ts.EndUpdate;
{$ENDREGION}

Result:=ts;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
ts:TStrings;
begin
ts:=TStringList.Create;

ts:=MyFun(ts);
{$REGION 'do something'}
ShowMessage(ts.Text);
{$ENDREGION}

ts.Free;
end;

[/code]


方案二
[code delphi]
procedure MyFun(var ts:TStrings);
var
i:integer;
begin

{$REGION 'do something'}
ts.BeginUpdate;
for i := 65 to 70 do
ts.Append(Chr(i));
ts.EndUpdate;
{$ENDREGION}

end;
procedure TForm1.Button1Click(Sender: TObject);
var
ts:TStrings;
begin
ts:=TStringList.Create;

MyFun(ts);
{$REGION 'do something'}
ShowMessage(ts.Text);
{$ENDREGION}

ts.Free;
end;
[/code]


按照提示,我想了兩個方案

不知道是不是這樣一個意思?
程式正常執行,
這樣算是正確的方法嗎?

P.D.
版主


發表:571
回覆:3888
積分:3677
註冊:2006-10-31

發送簡訊給我
#4 引用回覆 回覆 發表時間:2014-09-22 23:52:34 IP:59.120.xxx.xxx 未訂閱
我想, 用簡單一點的說明來表示(不確定觀念上是否正確)
1. 在 function 的流程中, 雖然 Result:= ts 已指定回傳, 但function 必須結束才會真實回傳result 值, 所以在result 下又釋放ts, 結果造成 ts 記憶體位址不見,
2. 在 function 區域中定義的變數, 有效期只限於 function 內, 按delphi 的慣性, ts 是會自動釋放 ts的, 所以無須自己手動下
3. 如果不放心的話, 可以把 ts 定義成一個 private 變數, 這樣在 form create中建立 ts, 在 form close 才釋放,

參考看看!
===================引 用 boy330077 文 章===================

[code delphi]
function MyFun:TStrings;
var
ts:Tstrings;
begin
ts:=TStringList.Create;

//---do something
Result:=ts;
//--- ts.free 這邊 FREE 會錯
end;

procedure TForm1.Button1Click(Sender: TObject);
var
ts:TStrings;
begin
ts:=TStringList.Create;

ts:=MyFun;
//--do something
ts.Free;
end;

[/code]


如上面
在 MyFun 裡面 FRee會錯 不Free又覺得怪怪的
本來想以 記憶體位置 檢查是否依然存在未釋放
但是對指標與記憶體不熟
想請問高手 正確方法因該如何使用
感謝指導
boy330077
一般會員


發表:39
回覆:59
積分:19
註冊:2009-10-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2014-09-23 08:40:59 IP:211.20.xxx.xxx 訂閱
感謝兩位高手指導

所以 P.D 大的意思 就是宣告在副程式內的 TSTRINGLIST 我不用擔心只要跳離他就會被回收

"自己CREATED 的自己FREE" 是只有在上方的全域才要遵守的意思嗎
編輯記錄
boy330077 重新編輯於 2014-09-23 09:35:29, 註解 無‧
P.D.
版主


發表:571
回覆:3888
積分:3677
註冊:2006-10-31

發送簡訊給我
#6 引用回覆 回覆 發表時間:2014-09-25 22:45:56 IP:59.120.xxx.xxx 未訂閱
我所學習到的知識是這樣的, 至於觀念是否正確, 並未實際去探討求證!
===================引 用 boy330077 文 章===================
感謝兩位高手指導

所以 P.D 大的意思 就是宣告在副程式內的 TSTRINGLIST 我不用擔心只要跳離他就會被回收

"自己CREATED 的自己FREE" 是只有在上方的全域才要遵守的意思嗎
leveon
資深會員


發表:30
回覆:386
積分:303
註冊:2012-02-12

發送簡訊給我
#7 引用回覆 回覆 發表時間:2014-09-26 16:10:38 IP:1.164.xxx.xxx 訂閱
在哪學到的知識?

ts不管放在哪 自己create的 就要自己free
基本觀念不清楚 寫出來的程式
出現莫名其妙的access violation肯定很多

不需要create的區域性變數 如string integer 才會自己回收
不過這個"知識"也沒啥好強調的 如果用個string integer
用完都要自己"free" 那delphi可以直接扔了


===================引 用 P.D. 文 章===================
我所學習到的知識是這樣的, 至於觀念是否正確, 並未實際去探討求證!
===================引 用 boy330077 文 章===================

感謝兩位高手指導

所以 P.D 大的意思 就是宣告在副程式內的 TSTRINGLIST‚ 我不用擔心只要跳離他就會被回收

"自己CREATED 的自己FREE"‚ ‚ 是只有在上方的全域才要遵守的意思嗎
pcplayer99
尊榮會員


發表:142
回覆:740
積分:591
註冊:2003-01-21

發送簡訊給我
#8 引用回覆 回覆 發表時間:2014-09-29 12:28:09 IP:183.15.xxx.xxx 訂閱
1. 对于 string, Integer 等不需要创建的变量,也就不需要释放。

2. 对于 Delphi 来讲,只要是你 Create 的【Object】,你都要 Free,不管是局部还是全局。
2.1. 如果那个 Object 是基于 Interface 的,继承自 TInterfacedObject,你在使用它的 Interface,你不用去做 Free 的动作。接口引用计数到0,它自己会释放。但你最好把引用到的接口变量设置为 nil 来让它释放。

----------------------------

如果要想代码不容易出现 Memory leak 内存泄漏,最好是哪里创建,哪里释放。这样不容易忘记释放导致内存被占用越来越多。

基于以上原因,代码通常有几种写法(我自己总结的,不是标准):

A.

function TAAA.DoSomeThingWithStrings(SL: TStringList): Boolean;
begin
SL.xxxxx
XXXXX(SL);
end;

procedure TAAA.DoSomeThing;
var
SL: TStringList;
begin
SL := TStringList.Create;
try
Do. xxxxx;
Do. YYYY;
DoSomeThingWithStrings(SL);
finally
SL.Free;
end;
end;



-----------------------
B.

function TBBB.DoSomeThingReturnStringList: TStringList;
begin
Result := TStringList.Create;
Do....XXXX;
Do....YYYY;
end;


procedure TBBB.DoSomeThing;
var
SL: TStringList;
begin
Do...XXX;

SL := Self.DoSomeThingReturnStringList;
try
DoSomething....
SL.XXXXX

Dodo(SL);
......
finally
SL.Free;
end;
end;
系統時間:2017-12-14 12:28:23
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!