我想知道何时在堆栈中清除内存,而堆栈是为本地函数调用分配的。我在一些视频教程中看到,当函数调用返回主时,分配给本地函数的内存将被清除。我对下面的节目有几个问题,请解释。
#include<stdio.h>
void print(){
printf("testing \n");
}
int* sum(int* a, int* b){
int c = *a + *b;
return &c;
}
int main(){
int a=3,b=2;
int *ptr = sum(&a,&b);
print();
printf("sum is: %d",*ptr);
return 0;
}
当我运行上面的程序时,它打印的是期望的垃圾值。但是,如果我在main中注释了"print()“函数,然后运行程序,那么它就是打印了正确的sum值。
发布于 2015-04-26 08:57:48
C没有堆栈,甚至在标准(C89、C99或C11)中都没有提到堆栈。实现可以使用堆栈来提供C抽象机器的行为方面,但它是标准指定的抽象机器本身。
因此,当堆栈被清除时(假设它甚至存在),这完全取决于实现。您所做的基本上是未定义的行为,在对象的生存期结束后访问它,所以结果可以是实现选择的任何东西。
至于为什么在特定实现的项目生命周期结束后可以访问这些项,很可能是因为输入和退出函数不能清除堆栈,它只是调整堆栈指针(比清除内存效率高得多)。
因此,除非某个东西覆盖了该内存位置的内容(例如对printf
的后续调用),否则它很可能将保持在上次设置的任何位置。
作为示例,下面是一个函数的prolog代码示例:
push ebp ; Save the frame pointer.
mov ebp, esp ; Set frame pointer to current stack pointer.
sub esp, XX ; Allocate XX space for this frame.
及其相应的epilog:
mov esp, ebp ; Restore stack pointer.
pop ebp ; Get previous frame pointer.
ret ; Return.
请注意,空间的分配(prolog中的sub
)和空间的取消分配(epilog中的mov
)实际上都没有清除它正在使用的内存。
然而,正如所述,是不应该依赖的.
发布于 2015-04-26 19:36:30
您的问题的答案是操作系统特定的。在从头创建进程(VMS/NT)的系统中,堆栈只有在创建进程时才会被清除。堆栈是从零需求页创建的。当首次访问堆栈页时,操作系统将创建新的零页。
在分叉系统中,每当加载新的可执行文件时,堆栈就会被清除。通常情况下,流程与上述相同。
在创建堆栈之后,放置在那里的任何内容都会一直留在那里,直到覆盖。
堆栈由操作系统管理,而不是编程语言管理。
https://stackoverflow.com/questions/29875558
复制相似问题