当堆栈上的内存被清除为本地函数时?

我想知道什么时候准确地清除了分配给本地函数调用的堆栈中的内存。 我在某些视频教程中看到,当函数调用返回到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;
}

当我运行上述程序时,它正在打印预期的垃圾值。 但是如果我在主要注释“print()”函数然后运行程序它打印和的正确值。

  • 这是否意味着即使本地函数的执行在堆栈中完成,直到有另一个函数调用到堆栈,以前分配的内存不会被清除?

  • 如果我在“print()”中删除“printf”语句并保持main(“print()”)调用,那么我可以看到sum的结果正常。 为什么它没有覆盖栈中的内存?


  • 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.
    

    和其相当的结语:

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

    请注意,无论是分配空间(序言中的sub )还是解除分配( mov在epilog中)都不会清除它正在使用的内存。

    但是,如前所述,这不是您应该依赖的。


    您的问题的答案是特定于操作系统。 在从头开始创建流程的系统(VMS / NT)中,只有在创建流程时才会清除堆栈。 该堆栈从需求零页面创建。 当第一次访问堆栈页时,操作系统会创建一个新的零页。

    在分叉系统中,只要装载了新的可执行文件,堆栈就会被清除。 通常该过程与上述相同。

    在创建堆栈之后,无论放在哪里,都会一直存在,直到被覆盖。

    该堆栈由操作系统管理; 不是编程语言。

    链接地址: http://www.djcxy.com/p/14021.html

    上一篇: when the memory is cleared on stack for a local function?

    下一篇: What is exactly the base pointer and stack pointer? To what do they point?