作者adrianshum (Alien)
看板C_and_CPP
標題Re: [問題] 關於新手十戒的小問題
時間Sat Oct 31 13:58:37 2009
※ 引述《hn12303158 (2orx)》之銘言:
: 請位各位, 在新手十誡(6)中提到:
: "不可以在函式中回傳一個指向區域性自動變數的指標。否則,會得到垃圾值"
: 但我作了以下的實驗
: 實驗一:
: 定義typedef struct Obj
: Obj* createInstance() {
: Obj* tmp = (Obj*)malloc(sizeof(Obj));
: return tmp;
: }
: 然後在main()裡宣告Obj* obj1 = createInstance()
在 main 裡面的不是 "宣告"
: 這樣雖然函式回傳區域性指標, 但是程式還是運作正常
tmp 指向的東西不是區域性。
你分得出:
Obj* foo() {
Obj myObj;
return &myObj;
}
和
Obj* foo() {
Obj* myObj = (Obj*) malloc(sizeof(Obj));
return myObj;
}
的分別嗎?
前者 return 的 ptr, 指向的是 local 的 variable (在 stack 的),
foo() 完結後,指向的那堆東西就失效了.
後者指向的是從 heap allocate 的。
玩得奸詐一點:
Obj** foo() {
Obj* myObj = (Obj*) malloc(sizeof(Obj));
return &myObj;
}
這樣會出問題嗎?
答案是一樣會,因為回傳的 ptr, 是指向 myObj,
而 myObj 是在 stack.
: 實驗二:
: 定義typedef struct Obj
: void createInstance(Obj* obj) {
: if (obj == NULL) {
: obj = malloc(Obj*)malloc(sizeof(Obj));
: }
: return;
: }
: 然後在main裡宣告Obj* obj = NULL;
: createInstance(obj);
: 實驗二中我用動態配置asign適當大小的記憶體給一個非區域變數,
: 沒有回傳區域變數的指標,
: 程式卻出現core dump(估計是記憶體被回收了)
: 請問這是怎麼回事呢?
: 我原本以為實驗一會失敗, 實驗二會成功,結果卻相反
: 麻煩各位幫忙解惑了, 謝謝!
這個單純是 pass-by-value 的概念。
你傳了 obj 進 function, 然後修改 obj 的
值,當然不會 caller 傳進去的東西。
情況就等如:
void foo(int i) {
i = 10;
}
int myInt = 5;
foo(myInt);
之後myInt 的值是多少?
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 203.218.221.177
推 hn12303158:case1的情況我知道了, 謝謝 10/31 17:08
→ hn12303158:但是case2我傳進去function裡的不是指標嗎? 10/31 17:09
→ hn12303158:那應該是call-by-reference吧? 10/31 17:09
→ walm20:錯 對於呼叫者,是傳一個記憶體位址給function 10/31 17:14
→ walm20:對於function,他用一個local的ptr去接這記憶體位址 10/31 17:14
→ walm20:這的確是pass-by-value 10/31 17:15
推 QQ29:對這是by value不過有人會講說這是Call by pointer~ 10/31 17:22
推 hn12303158:謝謝樓上幾位, 但我還是有點混淆 10/31 17:31
→ hn12303158:一般來說call-by-pointer和call-by-reference不都是 10/31 17:31
→ hn12303158:call-by-address嗎? 10/31 17:31
推 hilorrk:應該是call-by-pointer是call-by-value 但能用address的方 10/31 18:49
→ hilorrk:式模擬call-by-reference 10/31 18:49
推 hn12303158:哈 爬文後我了解了 10/31 18:56
推 andyjy12:我覺板上應該要有一張圖記憶結構的圖,方便說明 10/31 21:09
→ raincole:為什麼要把pointer解釋成模擬referenct..? 10/31 21:27
→ raincole:應該是先有pointer的概念吧... 10/31 21:28
推 twotwoone:要看你怎麼認定reference,某些認定上是reference沒錯 10/31 21:40