【问题标题】:C, what happens with the variables of a function when it finish?C、函数的变量在完成后会发生什么?
【发布时间】:2014-11-07 00:19:52
【问题描述】:

假设如下代码:

void foo()
{
    int i = 5;
    printf("%d", i);
}

int main()
{
    foo();

    return 0;
}

当我调用foo时,“i”被声明并设置为5,当这个函数完成时,“i”变量被释放?

我可以在没有内存泄漏风险的情况下在 while(1) 循环中调用 foo() 吗?

谢谢!

【问题讨论】:

  • 查看this answer 以更全面地了解堆栈的工作原理。

标签: c performance memory stack


【解决方案1】:

在 C 语言中,变量具有范围,即它们所属的代码区域,例如循环或函数。在这种情况下,你的变量的作用域就是你的函数。

当到达变量范围的末尾时,您的变量将被释放。这意味着您的变量使用的内存被释放。因此,在函数结束时,您分配的唯一内存空间(用于存储整数的内存空间)被释放。

要继续标题中的一般问题,您还可以分配将在声明范围之外持续存在的内存。

void foo()
{
    int i = 5;
    int* j = (int*) malloc(sizeof(int));
    *j = i*2
    printf("%d", i);
}

例如,在上面的代码中,i 和 j 变量都将在函数结束时被释放。

然而,j 是一个指针,它将被释放的是包含指针的内存空间,而不是包含 j 指向的实际值的内存空间(即使没有为 *j 分配值也是如此) .

为避免此处出现内存泄漏,您必须在退出函数之前调用 free(j)

如果函数返回int* 而不是void 类型,您也可以return j 而不是释放它,因此您仍然可以访问调用此函数的 j 指向的内存区域.这样做,您将能够使用该值,然后通过调用 free(j); 释放所使用的内存空间。

【讨论】:

  • 为了避免内存泄漏...你的函数 或者将该值返回给函数的调用者
【解决方案2】:

int i = 5;

在堆栈上声明一个 int 类型的变量。在堆栈上声明的变量在超出范围时释放它们的内存。 i 在函数完成后超出范围。

所以是的,您可以一遍又一遍地调用该函数而不会发生内存泄漏。

【讨论】:

    【解决方案3】:

    你不应该关心,你应该相信i 消失了。在我所知道的所有实现中,本地 i 要么在一个寄存器中,该寄存器被重用于其他目的,要么在一个被弹出的堆栈帧中。参见例如call stacks 上的维基页面提供了一张漂亮的图片。

    AFAIU,C99 标准规范中没有任何内容需要堆栈,但我知道没有不使用任何堆栈的实现。

    当然,您可以在main 内循环调用foo

    我建议用所有警告和调试信息(例如gcc -Wall -g)编译您的代码,并使用调试器(例如gdb)逐步运行您的程序并显示i的地址

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-17
      • 2018-04-08
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多