【发布时间】:2014-10-13 16:00:46
【问题描述】:
char *getString()
{
char str[] = "Will I be printed?";
return str;
}
int main()
{
printf("%s", getString());
getchar();
}
输出不应该是“我会被打印吗?” ?相反,输出结果是一些垃圾值。为什么会这样?
【问题讨论】:
char *getString()
{
char str[] = "Will I be printed?";
return str;
}
int main()
{
printf("%s", getString());
getchar();
}
输出不应该是“我会被打印吗?” ?相反,输出结果是一些垃圾值。为什么会这样?
【问题讨论】:
char str[] = "Will I be printed?";
是本地声明。它受限于函数getString()。当您离开该功能时,str[] 将被折叠。
所以你正试图在它上面打印数据。显然你会垃圾价值!
为了避免这种情况 -
char *str = "Will I be printed?";
现在str 将存储在代码内存中,当您离开函数时,str 不会被折叠。现在它将打印Will I be printed?
【讨论】:
因为当您离开 getString 函数时,您的局部变量 str 将超出范围。
【讨论】:
一旦你退出函数,str的值将是免费的,你应该使用:
char *str = "Will I be printed?";
return str;
你应该对堆栈和堆有所了解。
【讨论】:
你正在返回一个局部变量的地址,这是被禁止的,但是你可以通过这种方式返回一个字符串字面量:
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 */
}
【讨论】:
您在函数getString 的范围内声明了一个局部变量。当函数结束时,就在它返回值之前,该变量str 的内存被释放并清理,因为作用域已经结束。
现在函数将地址返回到这个清理过的内存。在许多情况下,当您访问内容时,内容已经被其他进程覆盖。所以它看起来像垃圾值。
【讨论】:
str 数组位于 getString() 函数内(本地范围)。与所有局部变量一样,它的存储空间通常会分配在堆栈上。
因此,在返回时,它将被自动释放。
【讨论】:
这里char str[] 是局部变量(自动)。在您的情况下,变量的范围仅限于函数 getString 。
所以在函数getString之外访问str的地址会导致未定义的行为。
但代码可以如下更正
char *getString()
{
char *str = "Will I be printed?";
return str;
}
int main()
{
printf("%s", getString());
getchar();
}
【讨论】:
这三个功能有很大区别
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?
因为对于这个简单的程序,堆栈可能不会被覆盖。
最后两个函数定义良好,因为返回的字符数组和字符串字面量指针具有静态存储持续时间。所以在退出函数后,这两个对象都会活着。
【讨论】: