副程式 TStrings 回傳與釋放 |
答題得分者是:herbert2
|
boy330077
一般會員 ![]() ![]() 發表:39 回覆:59 積分:19 註冊:2009-10-15 發送簡訊給我 |
[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 回覆:640 積分:894 註冊:2004-04-16 發送簡訊給我 |
在自訂的 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 發送簡訊給我 |
方案一
[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.
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
我想, 用簡單一點的說明來表示(不確定觀念上是否正確)
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 發送簡訊給我 |
|
P.D.
版主 ![]() ![]() ![]() ![]() ![]() ![]() 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
leveon
資深會員 ![]() ![]() ![]() ![]() ![]() 發表:30 回覆:389 積分:303 註冊:2012-02-12 發送簡訊給我 |
在哪學到的知識?
ts不管放在哪 自己create的 就要自己free 基本觀念不清楚 寫出來的程式 出現莫名其妙的access violation肯定很多 不需要create的區域性變數 如string integer 才會自己回收 不過這個"知識"也沒啥好強調的 如果用個string integer 用完都要自己"free" 那delphi可以直接扔了 ===================引 用 P.D. 文 章=================== 我所學習到的知識是這樣的, 至於觀念是否正確, 並未實際去探討求證! ===================引 用 boy330077 文 章=================== 感謝兩位高手指導 所以 P.D 大的意思 就是宣告在副程式內的 TSTRINGLIST‚ 我不用擔心只要跳離他就會被回收 "自己CREATED 的自己FREE"‚ ‚ 是只有在上方的全域才要遵守的意思嗎 |
pcplayer99
尊榮會員 ![]() ![]() ![]() ![]() ![]() ![]() 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
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; |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |