#include <stdio.h>
void function()
{
int stackVar = 10;
printf("Stack variable = %d\n", stackVar);
}
int main(void)
{
function();
return 0;
}
What happens to the stack frame of function
when it returns?
这是未定义的行为(与实现定义或未指定相反)。这意味着该程序可以随意行为不端,或者不以任何方式取悦。
这在6.2.4 对象的存储持续时间中有详细说明:
1 对象具有决定其生命周期的存储期限。共有三种存储持续时间:静态、自动和分配。分配的存储在 7.20.3 中描述。
2 对象的生命周期是程序执行期间保证为其保留存储的部分。一个对象存在,有一个不变的地址,并在其整个生命周期中保留其最后存储的值。如果对象在其生命周期之外被引用,则行为未定义。当指针指向的对象到达其生命周期的末尾时,指针的值变得不确定。
3 使用外部或内部链接或存储类说明符 static 声明其标识符的对象具有静态存储持续时间。它的生命周期是程序的整个执行过程,它的存储值只在程序启动之前初始化一次。
4其标识符被声明为没有链接且没有存储类说明符 static 的对象具有自动存储持续时间。
5 对于这种不具有可变长度数组类型的对象,其生命周期从进入与其关联的块开始,直到该块的执行以任何方式结束。(进入封闭的块或调用函数会暂停,但不会结束当前块的执行。)如果递归地进入块,则每次都会创建一个新的对象实例。对象的初始值是不确定的。如果为对象指定了初始化,则在执行块时每次到达声明时都会执行它;否则,每次达到声明时,该值变得不确定。
首先,您已经对问题进行了大幅编辑,因此其他答案(有点不公平)不再相关。不过,要回答当前的问题:
返回时函数的堆栈帧会发生什么?
在我看来,您对堆栈的运行方式缺乏总体感觉。所以 - 在这里有点疯狂 - 但会尝试一个可能使它“点击”的类比。您可以将堆栈帧想象成海滩上的波浪。嵌套的函数调用越深,这些函数在参数和局部变量中的数据越多,使用的内存就越多。这就像海浪到达海滩更远的地方。随着作用域的退出,内存被有效地释放——忘记了该内存的用途。海浪也会退去。尽管如此,在程序的整个生命周期中,随着不同的函数序列进入和退出,相同的内存(海滩的水平)被重复使用(在水下)和被遗忘(而不是在水下)。离海滩最远的地方往往被覆盖的频率最低,持续时间也很短,main()
呆在那里直到程序终止。
您正在调用未定义的行为。
当您从函数返回时,堆栈帧被破坏(超出范围),您可能会收到留在函数中的值,但这只是巧合。
有关一些示例,请参阅Wikipedia ,并在此处查看文章。
未定义的行为。您正在从函数返回局部变量地址,因为堆栈帧已被破坏(超出范围)。现在,如果内存(地址)没有被覆盖,那么您将获得相同的值,否则您将获得垃圾。