假设以下代码:
void foo()
{
int i = 5;
printf("%d", i);
}
int main()
{
foo();
return 0;
}
当我调用foo时,声明“i”并设置为5,当此函数完成时,“i”变量被释放?
我可以在没有内存泄漏风险的while(1)循环中调用foo()吗?
谢谢!
答案 0 :(得分:4)
在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);
来释放所使用的内存空间。
答案 1 :(得分:2)
int i = 5;
在堆栈上声明int类型的变量。堆栈上声明的变量在超出范围时释放内存。该功能完成后i
超出范围。
所以是的,你可以一遍又一遍地调用那个函数,没有内存泄漏。
答案 2 :(得分:1)
你不应该在乎,你应该相信i
消失了。在我所知道的所有实现中,本地i
或者位于寄存器中,该寄存器被重用于其他目的,或者存在于弹出的堆栈帧中。参见例如call stacks上的wikipage给出了一幅很好的图片。
AFAIU,C99标准规范中的任何内容都不需要堆栈,但我知道没有任何实现不使用任何堆栈。
当然,您可以在foo
内的循环中调用main
。
我建议使用所有警告和调试信息(例如gcc -Wall -g
)编译代码并使用调试器(例如gdb
)逐步运行程序并显示{{的地址1}}