2013-08-24 86 views
1

節目#1:爲什麼這些程序(僅在一個printf語句中有所不同)具有不同的輸出?

#include<stdio.h> 
#include<stdlib.h> 
char *getString() 
{ 
    char str[] = "GfG"; 
    printf("%s \n", str); 
    return str; 
}  
int main() 
{ 
    printf("%s", getString()); 
    return 0; 
} 

輸出:

GfG 
GfG 

節目#2:

#include<stdio.h> 
#include<stdlib.h> 
char *getString() 
{ 
    char str[] = "GfG"; 
    return str; 
}  
int main() 
{ 
    printf("%s", getString()); 
    return 0; 
} 

輸出:

(垃圾值)

請解釋爲什麼,因爲只有printf語句輸出不同。什麼是確切的描述?

+3

請不要大喊。 –

+0

'char * str =「GfG」;'?這對你的問題會是一個有趣的補充。特別是如果你讓他們'const char *'。 – trojanfoe

回答

10

因爲這兩個程序都顯示未定義的行爲。

getString函數返回str數組對象被銷燬並試圖在其生存期後訪問它是未定義的行爲。

您可以使用字符串文字修改你的程序,因爲串文字具有靜態存儲時間和他們的一生是程序的整個持續時間:

char *getString(void) 
{ 
    char *str = "GfG"; 
    return str; 
} 
+3

對於'return'和'str'都要確保'const char *'。可能某些編譯器可能不會強制執行「不允許寫入常量字符串」規則。 – trojanfoe

3
char str[] = "GfG"; 

聲明的自動變量。只有在聲明的範圍內(函數getString)才能訪問它。試圖在任何地方使用它會導致未定義的行爲。你不幸的是,第一個版本似乎工作。

getString返回時,可以重新使用用於存儲str的堆棧區域。如果發生這種情況,printf將最終通過內存進一步讀取,直到找到'\0'字節或崩潰。

1

您必須分配內存malloc或嘗試static

+1

這並不能解釋任何事情。 – trojanfoe

+1

沒有必要像其他人一樣重複同樣的事情。我的回答告訴我如何解決這個問題。 –

1

只要記住數組中的值不會在C中傳遞,它們會通過地址傳遞。由於strgetstring()中定義,在控制返回到main()後,訪問該特定地址無效。如果您碰巧訪問該地址,結果將不可預知。請記住,C編譯器不檢查程序中不正確的內存訪問請求。

0

在這兩種情況下,char str[] = "GfG";都放在堆棧裏面的第一個函數中。它返回一個指針。來電者嘗試使用它並將其提供給printf(),但與此同時,「舊」堆棧內容已被覆蓋。

它們之間可能存在差異,這會使第一個保留舊內容的時間更長一些,但不能保證這一點,因此它是未定義的行爲。

+2

我只是試過了,看起來在第二個版本中,字符串被靜靜地優化掉了:它不在函數內部使用,並且返回它是UB。所以它只是下降。 – glglgl

1

局部變量char str[] = "GfG";範圍僅限於該功能。所以當你試圖在函數範圍內打印時,它就可以工作。但是,當您試圖訪問從外部該函數的undefined behavior.

#include<stdio.h> 
#include<stdlib.h> 
char *getString() 
{ 
    char str[] = "GfG"; // Local variable, so once you try to return that it is undefined 
    return str; 
}  
int main() 
{ 
    printf("%s", getString()); 
    return 0; 
} 

經過下面的鏈接,你會得到一些更多的例子。 Does local variable be deleted from memory when this function is called in main

相關問題