char *getString()
{
char str[] = "Will I be printed?";
return str;
}
int main()
{
printf("%s", getString());
getchar();
}
输出不应该是“我会被打印吗?” ?相反,输出将成为一些垃圾值。为什么会这样?
答案 0 :(得分:6)
char str[] = "Will I be printed?";
是一份本地声明。它在函数getString()
中受限。当您离开该功能时,str[]
将被折叠。
所以你试图在它上面打印数据。显然你会垃圾值!
为避免这种情况 -
char *str = "Will I be printed?";
现在str
将存储在代码存储器中,当您离开该功能时,str
将不会被折叠。现在它将打印Will I be printed?
答案 1 :(得分:3)
因为当您离开str
函数时,您的本地变量getString
超出了范围。
答案 2 :(得分:3)
您正在返回本地变量的地址,这是禁止的,但您可以通过以下方式返回字符串文字:
char *getString()
{
char *str = "Will I be printed?";
return str; /* read only */
}
或
char *getString()
{
return "Will I be printed?"; /* read only */
}
或
char *getString()
{
static char str[] = "Will I be printed?";
return str; /* read - write */
}
答案 3 :(得分:3)
一旦你退出该功能,str的值将是免费的,而你应该使用:
char *str = "Will I be printed?";
return str;
你应该对堆栈和堆有一些了解。
答案 4 :(得分:2)
str
数组位于getString()
函数内(本地范围)。与所有局部变量一样,它的存储将通常在堆栈上分配。
因此,在返回时,它将自动解除分配。
答案 5 :(得分:2)
您在函数getString
的范围内声明了一个局部变量。当函数结束时,就在它返回值之前,该变量str
的内存被释放并清理,因为范围已经结束。
现在该函数将地址返回到此已清理的内存。在许多情况下,当您访问内容时,内容已被其他进程覆盖。所以它看起来像垃圾值。
答案 6 :(得分:2)
这里char str[]
是局部变量(auto)。在您的情况下,变量的范围仅限于函数getString。
因此,访问函数str
之外的getString
地址将导致未定义的行为。
但代码可以如下修正
char *getString()
{
char *str = "Will I be printed?";
return str;
}
int main()
{
printf("%s", getString());
getchar();
}
答案 7 :(得分:1)
这三个功能之间存在很大差异
char *getString()
{
char str[] = "Will I be printed?";
return str;
}
char *getString()
{
static char str[] = "Will I be printed?";
return str;
}
char *getString()
{
char *str = "Will I be printed?";
return str;
}
使用第一个函数会导致未定义的行为,但在大多数情况下会出现输出字符串
Will I be printed?
因为对于这个简单的程序,堆栈可能不会被覆盖。
最后两个函数定义良好,因为返回的字符数组和字符串文字指针具有静态存储持续时间。因此,退出函数后,两个对象都将存活。