2017-09-03 87 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

相关问题