【问题标题】:When will memory used in a function become free ??(C programming)函数中使用的内存何时会空闲??(C 编程)
【发布时间】:2011-09-28 06:17:07
【问题描述】:

下面是代码

代码:

#include <stdio.h>

int * num(void);

int main(void)
{
    int * num2;
    num2 =num();
    printf("%d\n" , *num2);

    return 0;
}


int * num(void)
{
    int num = 20;

    return &num;
}

问题:

    1234563这是main()
  1. 之后,我只需使用解引用运算符提取特定num 变量的值并在main() 函数中打印出来。

  2. 有一件事我很困惑。我记得我读过一本关于 javascript 的书,其中提到变量生命周期在函数中,这意味着在函数完成执行其指令并将控制权传递回调用它的函数后,函数中每个变量的值将是干净的out(garbage collector)。但是为什么在这段代码中我的main()函数仍然可以指向那个特定内存地址的值??

【问题讨论】:

  • main 中的代码之所以仍然可以指向那个内存地址,是因为与 JavaScript 不同,C 中没有垃圾收集器。
  • 呵呵,这点与下面的 4 个答案相矛盾
  • 我不知道你在看哪个答案,但是你在考虑动态范围吗?动态范围从堆栈中清除对象,是与垃圾回收不同的概念.

标签: c variables pointers memory-address


【解决方案1】:

之所以能看到变量的值,是因为堆栈的工作方式。实际上,当您输入函数num 时,会移动一个指针(堆栈指针)来为函数的本地存储添加空间。当您退出函数时,堆栈指针有效地向后移动,这意味着下一个函数调用将覆盖上一个函数调用中使用的堆栈存储。然而,在它被覆盖之前,该值处于一种不确定状态。它实际上仍然存在于内存中,但可能随时被覆盖。实际值的存在可能存在也可能不存在。这就是为什么像上面那样做被称为未定义的行为

基本上......不要这样做。

【讨论】:

    【解决方案2】:

    只是添加到@Goz 已经很好解释的内容。试试这个代码:

    #include <stdio.h>
    
    int * num(void);
    
    int fib(int n)
    {
        if( 0 == n || 1 == n )
            return n;
    
        return fib(n-1) + fib(n-2);
    }
    
    int main(void)
    {
        int * num2;
        num2 =num();
        (void)fib(7);
        printf("%d\n" , *num2);
    
        return 0;
    }
    
    
    int * num(void)
    {
        int num = 20;
    
        return &num;
    }
    

    很有可能你不会得到“20”作为输出(也有可能程序终止) 此外,当您编译时,编译器确实会警告您此“警告:函数返回局部变量的地址”:)

    【讨论】:

      【解决方案3】:

      返回一个指向局部变量的指针是不对的。当该函数返回时,变量num 被释放,并且该内存地址可以被 C 运行时用于另一个值。返回的指针现在无效,因为它指向一个未分配的内存区域,如果使用它会调用未定义的行为。未定义的行为意味着它可能会或可能不会做你想做的事。在某些情况下程序会崩溃,在其他情况下它可能会工作。为什么它在这种情况下起作用是因为那部分内存仍将保存值20。 C 运行时不会在释放后用 0 填充这部分内存。

      【讨论】:

        猜你喜欢
        • 2012-09-18
        • 2014-03-14
        • 1970-01-01
        • 2013-05-02
        • 2011-03-27
        • 2019-10-31
        • 2015-03-21
        • 2011-03-19
        • 1970-01-01
        相关资源
        最近更新 更多