C语言中,当一个函数执行完毕后,其中的变量会发生什么?

3

假设以下代码:

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

int main()
{
    foo();

    return 0;
}

当我调用foo函数时,“i”被声明并设置为5,当该函数结束时,“i”变量会被释放吗?
我可以在while(1)循环中调用foo()函数而不会有内存泄漏的风险吗?
谢谢!

2
查看这个答案,了解关于栈如何工作的更详细解释。 - Austin Mullins
3个回答

5
在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)来释放所使用的内存空间。

为了避免内存泄漏...你的函数应该将该值返回给函数的调用者。 - John Hascall

2

int i = 5;

这行代码在栈上声明了一个int类型的变量。在栈上声明的变量会在超出作用域时释放其内存。当函数结束时,i也将超出作用域。

因此,您可以反复调用该函数而不会发生内存泄漏。


1

你不需要关心,相信 i 会消失。在我所知道的所有实现中,本地的 i 要么在一个寄存器中被重用,要么在一个堆栈帧中被弹出。例如,可以查看 调用堆栈 的维基页面,其中提供了一张很好的图片。

据我所知,C99 标准规范中没有确切要求使用堆栈,但我不知道有哪个实现不使用任何堆栈。

因此,当然可以在 main 中的循环中调用 foo

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接