当内存堆栈上为本地函数清除? [英] when the memory is cleared on stack for a local function?

查看:165
本文介绍了当内存堆栈上为本地函数清除?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道什么时候内存中,分配给本地函数调用堆栈被清除。我已在一些视频教程看出,当函数调用返回到主被分配用于本地函数被清除的存储器。我有下面的程序几个问题,请解释一下。

 #包括LT&;&stdio.h中GT;无效的print(){
的printf(测试\\ n);
}为int *金额为(int *一,为int * B){
INT C = * A + * B;
返回和C;
}诠释主(){
诠释一个= 3,B = 2;
为int * PTR = SUM(安培;一,和b);
打印();
的printf(总和:%D,* PTR);
返回0;
}

当我运行上面的程序,它是印刷预计垃圾的价值。但是,如果我评论在主打印()函数,然后运行它是印刷总和正确的值的程序。


  1. 难道这意味着,即使本地函数的执行堆栈中完成,直到有另一个函数调用栈,previous分配的内存不被清除?


  2. 如果我删除的printf语句中的打印(),并保持打印()中的主要调用,那么我可以看到总和为正常的结果。为什么它没有覆盖堆栈内存?



解决方案

C 的任何堆栈,字堆栈甚至没有在标准(C89,C99提到的 C11)。一个的实施的可以使用堆栈提供的C抽象机的行为方面,但它的抽象机器本身该标准规定。

所以,当堆栈被清除(假设它存在的话),在这个时候,完全取决于执行。你在做什么基本上都是不确定的行为,访问对象其生命周期结束后,这样的结果可以是任何实现选择。

至于为什么,您可以访问项目后,他们的一生已经结束了的具体的实施,很可能是因为进入和退出功能的的清除栈,它只是调整堆栈指针(很多不必清除内存,以及更有效)。

所以,除非有覆盖相应位置内存什么的(如后续调用的printf ),它可能会保持在任何它上次的设置。

举例来说,这里是一个样本序言code的功能:

 推EBP;保存帧指针。
MOV EBP,ESP;设置帧指针到当前堆​​栈指针。
子ESP,XX; XX分配空间,此帧。

和它的等效结语:

  MOV ESP,EBP;恢复的堆栈指针。
流行EBP;获得previous帧指针。
RET;返回。

注意的空间,无论是分配(的序言),也不它( MOV 在释放收尾)实际上清除的它使用的内存。

然而,如前所述,这不是你应该依靠。

I want to know when exactly the memory is cleared in stack which is allocated for local function calls. I have seen in some video tutorial when the function call is returned to main the memory which is allocated for local function is cleared. I have few questions on below program, please explain.

#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;
}

when I run the above program, it is printing garbage value which is expected. But if I comment "print()" function in main and then run the program it is printing correct value of sum.

  1. Is this mean that even though the execution of local function is completed in stack, until there is another function call to the stack, the previous allocated memory is not cleared ?

  2. If I remove the "printf" statement in "print()" and keep the "print()" call in main, then I could see the result of sum as normal. Why it didn't overwrite the memory in stack?

解决方案

C has no stack, the word stack is not even mentioned in the standard (C89, C99 or C11). An implementation may use a stack to provide the behavioural aspects of the C abstract machine but it's the abstract machine itself which the standard specifies.

So, as to when the stack is cleared (assuming it even exists), that's something that's totally up to the implementation. What you are doing is basically undefined behaviour, accessing an object after its lifetime has ended, so the results can be anything the implementation chooses.

As to why you can access the items after their lifetime has ended for a specific implementation, most likely it's because entering and exiting a function doesn't clear the stack, it simply adjusts the stack pointer (a lot more efficient than having to clear the memory as well).

So, unless something overwrites what's at that memory location (such as a subsequent call to printf), it'll probably remain at whatever it was last set to.

By way of example, here's a sample prolog code for a function:

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.

and its equivalent epilog:

mov   esp, ebp  ; Restore stack pointer.
pop   ebp       ; Get previous frame pointer.
ret             ; Return.

Note that neither the allocation of space (sub in the prolog) nor the deallocation of it (mov in the epilog) actually clears the memory it's using.

However, as stated, it's not something you should rely on.

这篇关于当内存堆栈上为本地函数清除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆