vid*_*dya 1 c memory-management
我想知道何时在堆栈中清除了内存,这是为本地函数调用分配的.我在一些视频教程中看到,当函数调用返回到main时,为本地函数分配的内存被清除.我对以下程序的问题很少,请解释一下.
#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;
}
Run Code Online (Sandbox Code Playgroud)
当我运行上面的程序时,它是打印垃圾值,这是预期的.但是如果我在main中注释"print()"函数然后运行程序则打印正确的sum值.
这是否意味着即使本地函数的执行在堆栈中完成,直到有另一个函数调用堆栈,先前分配的内存不会被清除?
如果我删除"print()"中的"printf"语句并在main中保持"print()"调用,那么我可以看到sum的结果正常.为什么它没有覆盖堆栈中的内存?
Ç 具有无堆叠,所述字堆栈未在标准(C89,C99甚至提到或 C11).一个实现可以使用堆栈提供的C抽象机的行为方面,但它的抽象机器本身该标准规定.
因此,关于何时清除堆栈(假设它甚至存在),这完全取决于实现.你正在做的基本上是未定义的行为,在它的生命周期结束后访问一个对象,所以结果可以是实现选择的任何东西.
至于为什么你可以在特定实现的生命周期结束后访问这些项目,很可能是因为进入和退出函数不清除堆栈,它只是调整堆栈指针(比清除它更有效)记忆也是如此).
因此,除非有东西覆盖了该内存位置的内容(例如后续调用printf),否则它可能会保留在上次设置的内容中.
举例来说,这是一个函数的示例序言代码:
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.
Run Code Online (Sandbox Code Playgroud)
及其等效的结语:
mov esp, ebp ; Restore stack pointer.
pop ebp ; Get previous frame pointer.
ret ; Return.
Run Code Online (Sandbox Code Playgroud)
请注意,空间的分配(sub在prolog中)和它的释放(mov在epilog中)实际上都不会清除它正在使用的内存.
但是,如上所述,这不是你应该依赖的东西.
| 归档时间: |
|
| 查看次数: |
562 次 |
| 最近记录: |