我在页面中遇到了一个示例,概述了在C结构中表示字符串的各种方法。它解释了在main之外的函数中定义的数组将存储在堆栈段中,因此在返回之后不一定存在可能导致运行时错误的数组。
突出显示为什么阵列失败返回时突出显示可能的重复因素返回的元素0返回的指针不再有效但是没有显示同一存储类别(自动)的原因变量是成功的,因为它们通过了移除的元素堆叠框架
“下面的程序可能会打印一些垃圾数据,因为字符串存储在函数getString()的堆栈帧中,并且在getString()返回后数据可能不存在。”
char *getString()
{
char str[] = "GfG"; /* Stored in stack segment */
/* Problem: string may not be present after getSting() returns */
return str;
}
int main()
{
printf("%s", getString());
getchar();
return 0;
}
我知道其他本地C变量也将在它们各自的堆栈帧中定义,显然它们可以返回,所以为什么它是数组的问题?
谢谢
不同之处在于返回值而不是返回指针。
当你这样做:
int f()
{
int x = 9;
return x;
}
int main()
{
int a = f();
printf("a=%d\n", a);
return;
}
这是有效的,因为即使x
在f
返回时超出范围,它也会返回存储在x
(本例中为9)中的值。然后将该值分配给a
并随后打印。
在您的示例中,您将返回一个数组。在大多数情况下,表达式中使用的数组会衰减为指向其第一个元素的指针。所以return str
和return &str[0]
一样。返回该指针值并传递给printf
。然后printf
尝试取消引用该指针,但它指向的内存(数组str
)不再有效。
因此,您可以从函数返回值,但如果该值是指向局部变量的指针,则它将无效。
这应该粗略地解释发生了什么,从getString()返回后,它的堆栈不再有效。
^ ^
| not valid | ^ ^
+------------+ | not valid |
str--> | "GfG" | | not valid | <---+
| --- | | not valid | |
| stack of | +------------+ |
| getString | | return(str)| ----+
+------------+ | --- |
| | | |
| stack of | | stack of |
| main() | | main() |
+------------+ +------------+
如果用gcc -W -Wall编译(应该总是使用那些选项),它应该给出警告:
warning: function returns address of local variable [-Wreturn-local-addr]
有两种情况:
int
或char
的简单值时,该变量在该本地函数中定义/声明。它成功发生,因为返回时实际上复制了值。"GfG"
中有字符串str
,当你执行return str
时,复制的值是str
中的值,这是数组的地址位置。因此,在这种情况下,数组位置(指针)被复制,而此数组的内容消失(因为内容在本地堆栈帧上)。