2012-05-23 65 views
0

我知道爲什麼這個工程:簡單的指針的指針

#include <stdio.h> 

void cool_number(int **number) { 
    int value = 42; 
    int *p = &value; 
    *number = p; 
} 

int main() { 
    int *number; 
    cool_number(&number); 
    printf("number is %d\n", *number); 
    return 0; 
} 

我不明白的是爲什麼這不(在我的機器它打印3700或類似的東西)。

#include <stdio.h> 

void cool_number(int **number) { 
    int value = 42; 
    int *p = &value; 
    int **x = &p; 
    number = x; 
} 

int main() { 
    int *number; 
    cool_number(&number); 
    printf("number is %d\n", *number); 
    return 0; 
} 

爲什麼不相等?

+1

你的第一個例子不 「工作」。返回局部變量的地址是未定義的行爲。這是一個錯誤,只有[出現意外工作](http://stackoverflow.com/a/6445794/445976)。 – Blastfurnace

+1

這是真的,但它與被問到的問題也不是完全相關的,這就是「爲什麼這兩個函數實現會做不同的事情」。即使OP修復了這個問題,他們仍然會發現這兩個功能的行爲不同,原來的問題仍然存在。 – aroth

+1

@aroth:我認爲試圖推斷出有未定義行爲的代碼是浪費時間。首先解決這個問題,然後再詢問通過值與參考值的關係。即使他糾正了通過這個問題的參數仍然可能是「爲什麼這兩個函數實現做不同的事情」。 – Blastfurnace

回答

2

我認爲它們不是等價的,因爲number是按照函數參數標準的值在堆棧上傳遞的。您在cool_number()中直接對number進行的任何更改都會修改堆棧上的本地副本,並且不會反映在number的值main()中。

在第一個例子中,通過取消引用number來解決這個問題,它告訴計算機修改內存中的某個特定位置,您也有一個指向main()的指針。在第二個例子中你沒有這個,所以發生的只是你將本地number指針指向其他地方,而沒有實際更新main()中引用的任何內存位置。因此,一旦你回到main(),你所做的任何事都不會顯示出來。

而且由於value是本地cool_number()功能,設置對它的引用,將後cool_number()回報是不能保證工作訪問,當然不應該在瑣碎/玩具例子之外的任何代碼中使用。但在這個特定的例子中,它並不是真的與你在兩段代碼之間看到不同的結果有關。

3

兩者都是邪惡的,因爲它們捕獲堆棧變量的地址。

第二個沒有你期待什麼,因爲你是直接把參數號,這只是暫時的分配,第一個改變什麼參數號指針,這是同樣的事情,在主穴數。

1

據我所知,在這兩種情況下,你的代碼都是錯誤的。

  1. 在第一種情況下,你是返回一個地址對堆棧中分配一個變量,它會立即釋放的函數返回。

  2. 在第二種情況下,第一種情況的錯誤存在,再加上您按值傳遞數字,因此更新號碼不會反映在調用者函數中。

在'C'中,參數總是按值傳遞。所以,你不能更新原樣傳遞的參數。對於防爆:

int func(int a) 
{ 
    a = 5; // In this case the value 5 will not be reflected in the caller as what is updated is the local copy of a on the stack 
} 

int func(int *a) 
{ 

    *a = 5; // This update will show in caller as you are directly updating the memory pointed to by a 
    a = malloc(4); //This update will not show in caller as again you are updating the local copy of stack  
} 
0
#include <stdio.h> 

void cool_number(int **number) { 
    int value = 42; /* this "value" hold 42 value, 
        and it lifetime is only in this function */ 
    int *p = &value; /* here we get the address of "value" in memory */ 
    *number = p; 
} 

int main() { 
    int *number; 
    cool_number(&number); /* after this function the "value" in memory had been recyled 
          and may be used by other program */ 
    printf("number is %d\n", *number); /* so when we print value here it will be 
           a unpredictable value, somehow may be crash */ 
    return 0; 
} 

兩個相同的原理