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

副程式回傳值及記憶體釋放

答題得分者是:暗黑破壞神
boss.tw
高階會員


發表:15
回覆:109
積分:194
註冊:2005-05-17

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-10-30 12:55:02 IP:200.65.xxx.xxx 訂閱
我想問的笨問題是,一時想不透,希望有人可以開導我一下
當一個副程式回傳前有記憶體空間必需被釋放時,該如何回傳才正確
但我又不想透過傳讓副程式存放的空間值給副程式
舉的例子有點爛,不知有沒有人看得懂

一個程式有個副程式 fun1
副程式 fun1 內,呼叫 fun2

[code cpp]
char *fun1(){
return fun2( "test1", "test2" );
}

char *fun2(char *a1, char *a2){
//把 a1 a2 串起來
//因為要回傳一個字串的位址,又如果透過strlen得到 a1, a2,再new一塊區域,但是出去此副程式前應該要釋放記憶體
//此時如何 return a1_a2,或是用什麼辦法
char * a1_a2 = new char[ strlen(a1) strlen(a2) ];
delete [] a1_a2;
//...該怎麼回傳呢
}
[/code]

暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-10-31 10:57:56 IP:114.137.xxx.xxx 未訂閱
我的寫法比較笨蛋化。不過,比較容易想得通。

方法一:function 2 要用到的空間指標。由 function 1 傳過去。
這樣可以做到的是在2所配的空間。可以由1來刪。

方法二:在 function2 不做 delete 而由 function 1 來做 delete
可是這樣使用的人,會忘記在 function 1 刪它。那就會出問題了。

boss.tw
高階會員


發表:15
回覆:109
積分:194
註冊:2005-05-17

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-11-01 22:45:09 IP:122.116.xxx.xxx 訂閱
暗黑破壞神您好
你提供的第一方法,就是我所說的傳讓副程式存放的空間值給副程式,也就是傳記憶體位置到 fun2,由fun2建立,由fun 1刪除
第二個方法,我猜你說的是,全域變數的位址讓 fun1, fun2 共用,而由fun2建立, fun 1 刪除
其實我想知道的方法類似 AnsiString s.cat_sprintf 的方法如下,它是怎麼辦到的

AnsiString Salutation = "Mr."
AnsiString s = "";
s.cat_sprintf("Dear %s ", Salutation);
s.cat_sprintf("%s,", "Smith");

results in an AnsiString with the value

Dear Mr. Smith,


===================引 用 暗黑破壞神 文 章===================
我的寫法比較笨蛋化。不過,比較容易想得通。

方法一:function 2 要用到的空間指標。由 function 1 傳過去。
這樣可以做到的是在2所配的空間。可以由1來刪。

方法二:在 function2 不做 delete 而由 function 1 來做 delete
可是這樣使用的人,會忘記在 function 1 刪它。那就會出問題了。

暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-11-01 23:04:39 IP:114.46.xxx.xxx 未訂閱
不對喔.
你搞錯我的意思了喔.
第一個方法. 你只是傳了個指標過去.而你在 function 所 new 的空間. 並不會因為你離開 function 2 而被收回.
記得,所有 new 的空間.都要手動 delete 才會收回.
我只要你傳指標過去. 我沒要你傳空間過去喔. 這兩個是有差的.

而第二個方法. 也是利用 new 之後要手動 delete 所以. 在 function 2 做的 new 你必須把 pointer 送回 function1 然後由 function 來做 delete 的動作.

其實.這兩種方法.都是比較傳統的方法.
新的方法是可以把它變成傳參考的方式.直接傳過去.
不過,我比較不相信編譯器的特異功能.比較相信基本的原則來寫的功能.

===================引 用 boss.tw 文 章===================
暗黑破壞神您好
你提供的第一方法,就是我所說的傳讓副程式存放的空間值給副程式,也就是傳記憶體位置到 fun2,由fun2建立,由fun 1刪除
第二個方法,我猜你說的是,全域變數的位址讓 fun1, fun2 共用,而由fun2建立, fun 1 刪除
其實我想知道的方法類似 AnsiString s.cat_sprintf 的方法如下,它是怎麼辦到的

AnsiString Salutation = "Mr."
AnsiString s = "";
s.cat_sprintf("Dear %s ", Salutation);
s.cat_sprintf("%s,", "Smith");

results in an AnsiString with the value

Dear Mr. Smith,


===================引 用 暗黑破壞神 文 章===================
我的寫法比較笨蛋化。不過,比較容易想得通。

方法一:function 2 要用到的空間指標。由 function 1 傳過去。
這樣可以做到的是在2所配的空間。可以由1來刪。

方法二:在 function2 不做 delete 而由 function 1 來做 delete
可是這樣使用的人,會忘記在 function 1 刪它。那就會出問題了。

boss.tw
高階會員


發表:15
回覆:109
積分:194
註冊:2005-05-17

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-11-01 23:28:16 IP:122.116.xxx.xxx 訂閱
所以您所說的如下囉
方法一
[code cpp]
fun1( void){
char *a1, *a2, *a1_a2;
a1 = "test1";
a2 = "test2";
fun2( a1_a2, a1, a2 );
delete [] a1_a2;
}
fun2( char *b1_b2, cahr * b1, char *b2){
b1_b2 = new char[strlen(b1) strlen(b2)];
strcpy( b1_b2, b1 );
strcpy( &b1_b2[strlen(b1_b2)-1], b2 );
}
[/code]

方法二
[code cpp]
char *a1_a2;
fun1( void){
char *a1, *a2;
a1 = "test1";
a2 = "test2";
a1_a2 = fun2( a1, a2 );
delete [] a1_a2;
}
char *fun2( cahr * b1, char *b2){
a1_a2 = new char[strlen(b1) strlen(b2)];
strcpy( a1_a2, b1 );
strcpy( &a1_a2[strlen(a1_a2)-1], b2 );
return a1_a2;
}
[/code]

===================引 用 暗黑破壞神 文 章===================
不對喔.
你搞錯我的意思了喔.
第一個方法. 你只是傳了個指標過去.而你在 function 所 new 的空間. 並不會因為你離開 function 2 而被收回.
記得,所有 new 的空間.都要手動 delete 才會收回.
我只要你傳指標過去. 我沒要你傳空間過去喔. 這兩個是有差的.

而第二個方法. 也是利用 new 之後要手動 delete 所以. 在 function 2 做的 new 你必須把 pointer 送回 function1 然後由 function 來做 delete 的動作.

其實.這兩種方法.都是比較傳統的方法.
新的方法是可以把它變成傳參考的方式.直接傳過去.
不過,我比較不相信編譯器的特異功能.比較相信基本的原則來寫的功能.

===================引 用 boss.tw 文 章===================
暗黑破壞神您好
你提供的第一方法,就是我所說的傳讓副程式存放的空間值給副程式,也就是傳記憶體位置到 fun2,由fun2建立,由fun 1刪除
第二個方法,我猜你說的是,全域變數的位址讓 fun1, fun2 共用,而由fun2建立, fun 1 刪除
其實我想知道的方法類似 AnsiString s.cat_sprintf 的方法如下,它是怎麼辦到的

AnsiString Salutation = "Mr."
AnsiString s = "";
s.cat_sprintf("Dear %s ", Salutation);
s.cat_sprintf("%s,", "Smith");

results in an AnsiString with the value

Dear Mr. Smith,


===================引 用 暗黑破壞神 文 章===================
我的寫法比較笨蛋化。不過,比較容易想得通。

方法一:function 2 要用到的空間指標。由 function 1 傳過去。
這樣可以做到的是在2所配的空間。可以由1來刪。

方法二:在 function2 不做 delete 而由 function 1 來做 delete
可是這樣使用的人,會忘記在 function 1 刪它。那就會出問題了。

編輯記錄
boss.tw 重新編輯於 2009-11-01 23:38:54, 註解 無‧
boss.tw 重新編輯於 2009-11-01 23:41:26, 註解 無‧
boss.tw 重新編輯於 2009-11-01 23:43:17, 註解 無‧
暗黑破壞神
版主


發表:9
回覆:2301
積分:1627
註冊:2004-10-04

發送簡訊給我
#6 引用回覆 回覆 發表時間:2009-11-02 03:27:14 IP:114.46.xxx.xxx 未訂閱
yes 差不多.
只是要加些防呆.
初始化跟要delete之前要確認是否為null.....etc的動作加下去.

syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#7 引用回覆 回覆 發表時間:2009-11-04 08:55:23 IP:59.125.xxx.xxx 訂閱
各位大大回答了一堆

小弟,稍微強調一下
應該是這樣解釋

副程式結束時,應將沒有使用,且必須自行釋放的記憶體空間加以釋放,這樣管理會比較好

但也沒人說不能在程式結束時,一起釋放

所以沒有規定一定要在副程式結束前釋放

觀念是 自己 new 的自己 free,但,時機由你決定

過於頻繁的 new 與 free,視狀況,有時也是不好的

===================引 用 boss.tw 文 章===================
我想問的笨問題是,一時想不透,希望有人可以開導我一下
當一個副程式回傳前有記憶體空間必需被釋放時,該如何回傳才正確
但我又不想透過傳讓副程式存放的空間值給副程式
舉的例子有點爛,不知有沒有人看得懂

一個程式有個副程式 fun1
副程式 fun1 內,呼叫 fun2

[code cpp]
char *fun1(){
return fun2( "test1", "test2" );
}

char *fun2(char *a1, char *a2){
//把 a1 a2 串起來
//因為要回傳一個字串的位址,又如果透過strlen得到 a1, a2,再new一塊區域,但是出去此副程式前應該要釋放記憶體
//此時如何 return a1_a2,或是用什麼辦法
char * a1_a2 = new char[ strlen(a1) strlen(a2) ];
delete [] a1_a2;
//...該怎麼回傳呢
}
[/code]

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