我对悬挂指针有一个想法。我知道下面的程序会产生一个悬空指针。但是我无法理解程序的输出
char *getString()
{
char str[] = "Stack Overflow ";
return str;
}
int main()
{
char *s=getString();
printf("%c\n",s[1]);
printf("%s",s); // Statement -1
printf("%s\n",s); // Statement -2
return 0;
}
以下程序的输出是 Ť 如果只有Statement-1那么输出就是一些垃圾值 如果只有Statement-2,则输出为新行
答案 0 :(得分:2)
您的代码显示undefined behaviour,因为您要返回本地变量的地址。
str
函数完成执行并返回后,不存在getString()
。
至于问题,
如果只有Statement-1那么输出是一些grabage值,如果只有Statement-2那么输出是新行
没有解释。一旦您的程序显示未定义的行为,就无法预测输出,这就是全部。 [谁知道,它也可能打印你的手机号码,或者守护进程可能会从我的鼻子里飞出来]
对于简单的逻辑部分,在\n
中添加printf()
将导致输出缓冲区立即刷新到输出。 [提示:stdout
是行缓冲的。]
<强>解决方案:强>
您可以通过以下两种方式完成工作
getString()
内动态分配内存并返回指针。 (我推荐这个)。此外,free()
稍后会在main()
中完成。{/ li>
char str[]
static
,以便范围不限于函数的生命周期。 (不太好,但仍然会做这个工作)答案 1 :(得分:0)
str
中的getString
是一个局部变量,在堆栈上分配,当函数返回时,它不再存在。
我建议你像这样重写getString()
char *getString()
{
char str[] = "Stack Overflow ";
char *tmp = (char*)malloc(sizeof(char)*strlen(str));
memcpy(tmp, str, strlen(str));
return tmp;
}
您需要添加
free(s);
之前return 0;
在我的例子中,指针tmp
指向堆上的块内存,它将一直存在直到程序结束
您需要了解有关stack and heap
的更多信息此外,还有另一种方法,使用静态变量
char *getString()
{
static char str[] = "Stack Overflow ";
return str;
}
PS:你得到以下陈述的正确答案printf("%c\n",s[1]);
只是巧合。从函数返回时,Opera System没有时间做一些干净的工作。但它会
答案 2 :(得分:0)
数组作为指针返回,但是从函数返回后数组本身就是垃圾。只需使用静态修饰符。
关于s [1]有什么问题。关键是,获取悬空指针后,它是第一个 printf。所以,此时的堆栈仍然(可能)完好无损。您应该记得,堆栈仅用于函数调用和局部变量(在DOS中它可以被系统中断使用,但现在情况并非如此)。因此,在第一个printf之前(当s [1]被计算时),s []是正常的,但是之后 - 它不是(printf'代码搞砸了)。我希望,现在很清楚。