2014-09-01 103 views
-2
#include <stdio.h> 
int ∗addition(int a, int b){ 
    int c = a + b ; 
    int ∗d = &c ; 
    return d ; 
} 

int main (void) { 
    int result = ∗(addition(1, 2)); 
    int ∗resultptr = addition(1, 2); 

    printf(」result = %d\n」, ∗resultptr); 
    printf(」result = %d\n」, result); 
    return 0 ; 
} 

這會給出正確的答案。但奇怪的是,一旦我交換了最後兩個printf()的順序,就會給出異常的答案。爲什麼顛倒printf()的順序會產生不同的輸出?

printf(」result = %d\n」, result); 
printf(」result = %d\n」, ∗resultptr); 

這是爲什麼?是否因爲printf()的一些內部實現?

我打開了-Wall選項,但沒有顯示警告。

謝謝你的回答!這是我在stackoverflow上的第一個問題。

但是爲什麼顛倒順序會給出不同的答案?如果這是由於未定義的返回一個局部變量的行爲,爲什麼第一個程序給出了正確的答案,但第二個程序不能,而唯一的區別是printf()的順序?

+0

是的,因爲通過返回局部變量的地址,並在函數返回後使用它,您將進入未定義行爲的領域。不,它不是因爲printf的內部實現。 – SuperSaiyan 2014-09-01 06:28:11

+2

請開啓,閱讀並理解編譯器警告。 – 2014-09-01 06:28:56

+0

可能的重複[可以訪問局部變量的內存超出其範圍?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) 。關注於C++,但是同樣適用於C. – juanchopanza 2014-09-01 06:30:29

回答

4

您正在返回一個指向局部變量的指針,該局部變量在函數退出後被釋放(從而調用未定義的行爲)。

+0

返回指向局部變量的指針不是問題所在。在調用函數中解引用該指針是問題所在。 – chux 2014-09-01 12:36:29

5

在這個函數中,

int ∗addition(int a, int b){ 
    int c = a + b ; // Object on the stack 
    int ∗d = &c ;  // d points to an object on the stack. 
    return d ; 
} 

要返回一個指針從堆棧的對象。從函數返回後返回的內存無效。訪問該內存導致未定義的行爲。

如果您更改函數以返回int,則事情會好的。

int addition(int a, int b){ 
    return (a + b); 
} 

int main (void) { 
    int result1 = addition(1, 2); 
    int result2 = addition(2, 3); 

    printf(」result = %d\n」, result1); 
    printf(」result = %d\n」, result2); 
    return 0 ; 
}