2012-05-07 55 views
0

下面兩個函數之間是否有任何區別並不在於兩種情況下返回的局部變量的地址,而是使用f1()函數返回正確的值4而不是f2()。另外在第三種情況下,我正確的說,字符串常量不會被存儲在堆棧中,所以當我們返回指針時它將正常工作。那麼字符串常量在哪裏存儲?字符串常量存儲

int* f1() 
{ 
    int* a=(int*)4; 
    return a; 
} 

int* f2() 
{ 
    int a=4; 
    return &a; 
} 

char* f3() 
{ 
    char* p="abcd"; 
    return p; 
} 
+0

這兩個函數是否有區別 - 而且您已經提供了3個函數! :) – tuxuday

+1

爲了記錄,您不應該返回指向堆棧變量的指針。在函數退出後,該內存很可能會用於其他內容。 –

+0

不應該有人做了一個諷刺評論「這是家庭作業」現在大聲笑 – UNECS

回答

6

有他們之間的所有差異:

  1. 第一返回一個int *與值4,注意它並不指向與價值4變量,但對地址4.
  2. 第二個函數返回一個指向保存爲4的變量的指針,但實際上這個指針是無效的,因爲它指向已經返回的函數的局部變量,並且它的任何用法都會導致未定義的行爲。
  3. 第三個返回一個指向char的指針(根據定義),但實際上這是一個指向字符串文字的指針(通過實現)。與它的問題是,作爲函數返回char *而不是const char *,可能會嘗試修改返回緩衝區,這將再次導致未定義的行爲。
+0

你們只是太快... – UmNyobe

+0

我知道我什至沒有打擾開始輸入答案 – UNECS

+0

在f3()哪裏是字符串文字實際上是存儲的(不是堆棧權限?),因爲即使在函數返回後我們也能夠訪問它。此外爲什麼是字符串文字const char *它只是語言構造或其他? – grv

1
  • f1值4投射到一個地址,在存儲器某處指向效果。
  • f2返回本地變量的地址。解引用這個指針將是未定義的行爲。
  • f3是一個指向字符串文字的指針。這是一個有效的指針,因爲字符串文字的生存期與程序生存期相同(靜態存儲期限)。這個文字的存儲位置由實現定義。操縱字符串文字的內容是未定義的行爲。
+0

是不是f1指向地址0x4(而不是「內存中的某個地方」)? –

+0

@ScottWilson正確。鑑於虛擬內存,我認爲這是「某處」:)每一個你沒有以安全的方式獲得的指針,或者對底層機器的核心知識都沒有獲得,所以它的價值無關緊要。 – pmr

+0

那麼所有的字符串文字都有靜態存儲?此外,爲什麼字符串文字定義爲const char *,它只是語言結構還是有一些原因? – grv

0
  • f1已明確指定地址4,並在該地址返回相同的,而不是價值。
  • 局部變量分配在堆棧上,因此在f2中返回&a,您返回的是堆棧中的地址,而不是存儲在該地址中的4。由於功能從堆棧中清除,因此取消引用該地址會導致未定義的行爲。
  • 字符串文本被分配在只讀數據部分和注意到

    char arr[]="abcd";char *ptr="abcd";

    第一之間的差是一個字符陣列和在堆棧上被分配而第二個是一個指向串文字(文字不指針)分配在只讀數據部分。

PS:我在這裏假設了GCC/x86。

+0

'f2'中沒有'could'。取消引用該指針是UB,無論已刷新或不刷新。 – pmr

+0

同意並編輯:) – toofast1227