为什么以下两个代码提供不同的结果?
问题描述:
-
的代码的第一部分是:为什么以下两个代码提供不同的结果?
#include <stdio.h> char *getString() { char *str = "Will I be printed?"; return str; } int main() { printf("%s", getString()); }
-
而且代码的第二部分是:
#include <stdio.h> char *getString() { char str[] = "Will I be printed?"; return str; } int main() { printf("%s", getString()); }
在上述两个码的,则返回字符指针,其指向一个可能被覆盖的局部变量,但仍然代码1管理成功运行,而代码2打印垃圾值。
答
让一点点扩展你的榜样,看看我们的存储数据:
#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()实际上会返回指向堆栈外的数据段的指针值,所以这个函数可以正常工作,但是在函数出口处分配的指针会被取消定义。
“在上述两个代码中,都返回指向局部变量的字符指针”否,只有第二个代码执行该操作。 – tkausl
这不是悬挂指针:),因为你的标签说。在第一种情况下,指针指向第二种情况下的字符串,它是一个读/写内存中的数组。 – MCG
@MCG在执行getString()之后,将取消分配变量的内存,因此该函数返回的指针值是悬挂指针 –