2017-09-03 122 views
-1
  1. 的代碼的第一部分是:爲什麼以下兩個代碼提供不同的結果?

    #include <stdio.h> 
    char *getString() 
    { 
        char *str = "Will I be printed?"; 
        return str; 
    } 
    int main() 
    { 
        printf("%s", getString()); 
    } 
    
  2. 而且代碼的第二部分是:

    #include <stdio.h> 
    char *getString() 
    { 
        char str[] = "Will I be printed?"; 
        return str; 
    } 
    int main() 
    { 
        printf("%s", getString()); 
    } 
    

在上述兩個碼的,則返回字符指針,其指向一個可能被覆蓋的局部變量,但仍然代碼1管理成功運行,而代碼2打印垃圾值。

+4

「在上述兩個代碼中,都返回指向局部變量的字符指針」否,只有第二個代碼執行該操作。 – tkausl

+0

這不是懸掛指針:),因爲你的標籤說。在第一種情況下,指針指向第二種情況下的字符串,它是一個讀/寫內存中的數組。 – MCG

+1

@MCG在執行getString()之後,將取消分配變量的內存,因此該函數返回的指針值是懸掛指針 –

回答

0

讓一點點擴展你的榜樣,看看我們的存儲數據:

#include <stdio.h> 

char* some_static_var="123"; 

char *getString1() 
{ 
    char *str = "Will I be printed?"; 
    return str; 
} 

char *getString2() 
{ 
    char str[] = "Will I be printed?"; 
    return str; 
} 

int main() 
{ 
    int some_var_at_stack=1; 
    printf("%p\n", &some_var_at_stack); 
    printf("%p\n", some_static_var); 
    printf("%p\n", getString1()); 
    printf("%p\n", getString2()); 
} 

我們得到了什麼?在我的32位系統:

0xbfc2005c

0x80497bc

0x8048554

0xbfc20035

正如你所看到的,字符* VAR = 「123」 中的數據點段(https://en.wikipedia.org/wiki/Data_segment),但char []位於堆棧。每一次,當你離開你的函數在堆棧中分配任何變量的地方時,這個變量會變得不確定,因爲在堆棧中分配的數據(指針也是)在外部函數中無效。但是在getString1()實際上會返回指向堆棧外的數據段的指針值,所以這個函數可以正常工作,但是在函數出口處分配的指針會被取消定義。

+0

是的,你說得對。 – bukkojot

+0

在不同的日子,它會格式化您的硬盤。 UB是UB。你的例子沒有解釋任何東西。它不會「得到未定義的行爲」,但它總是調用UB **。 C語言中沒有堆棧。 – Olaf

+0

我的例子顯示真實的內存佈局。如果你不知道你的應用程序的內存佈局(數據段,堆,堆棧),那麼你不能有效地使用C語言編寫代碼。 – bukkojot

相關問題