简体   繁体   English

C,函数完成后的变量会发生什么?

[英]C, what happens with the variables of a function when it finish?

Supposing the following code: 假设以下代码:

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

int main()
{
    foo();

    return 0;
}

When I call foo, "i" is declared and set to 5, when this function finish, the "i" variable is released? 当我调用foo时,声明“i”并设置为5,当此函数完成时,“i”变量被释放?

Can I call the foo() in a while(1) loop without memory leak risk? 我可以在while(1)循环中调用foo()而没有内存泄漏风险吗?

Thanks! 谢谢!

In C language, variables have a scope, an area of your code they belong to, like a loop or a function. 在C语言中,变量具有范围,即代码所属的区域,例如循环或函数。 In this case, the scope of your variable is your function. 在这种情况下,变量的范围就是函数。

When the end of the scope of your variable is reached, your variable is deallocated. 达到变量范围的末尾时,将取消分配您的变量。 This means the memory used by your variable is released. 这意味着您的变量使用的内存已释放。 So at the end of your function, the only memory space you allocated (the one you used to store an integer) is released. 因此,在函数结束时,将释放您分配的唯一内存空间(用于存储整数的内存空间)。

To continue on the general question in the title, you can also allocate memory that will persist outside the scope of your declaration. 要继续标题中的一般性问题,您还可以分配将保留在声明范围之外的内存。

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

For example, in the code above, both the i and j variable will be deallocated at the end of the function. 例如,在上面的代码中,i和j变量都将在函数末尾被释放。

However, j is a pointer, and it is the memory space containing the pointer that will be deallocated, not the memory space containing the actual value pointed by j (and this would be true even without allocating a value to *j). 但是,j是一个指针,它是包含将被释放的指针的内存空间,而不是包含j指向的实际值的内存空间(即使没有为* j分配值也是如此)。

To avoid a memory leak here, you would have to call free(j) before exiting your function. 为了避免此处发生内存泄漏,您必须在退出函数之前调用free(j)

If the function were returning an int* instead of being of type void , you could also return j instead of freeing it, so you would still have access to the memory area pointed by j where you called this function. 如果函数返回一个int*而不是void类型,你也可以return j而不是释放它,所以你仍然可以访问j所指向的内存区域,你调用了这个函数。 Doing so, you would be able to use the value and later deallocate the memory space used by calling free(j); 这样做,您将能够使用该值,并稍后通过调用free(j);释放所使用的内存空间free(j); .

int i = 5;

Declares a variable of int type on the stack. 在堆栈上声明int类型的变量。 Variables declared on the stack free their memory when they go out of scope. 堆栈上声明的变量在超出范围时释放内存。 i goes out of scope when the function is finished. 功能完成后, i超出了范围。

So yes, you can call that function over and over with no memory leak. 所以,是的,你可以反复调用该函数,没有内存泄漏。

You should not care, and you should believe that i vanishes. 您不在乎,您应该相信i消失了。 In all implementations I know about, that local i either was in a register which becomes reused for other purposes, or was in a stack frame which got popped. 在我所知道的所有实现中,本地i要么在一个寄存器中,它会被重用于其他目的,或者是在一个被弹出的堆栈帧中。 See eg the wikipage on call stacks which gives a nice picture. 参见例如电话堆栈上的wikipage,它给出了一个很好的图片。

AFAIU, nothing in the C99 standard specification exactly requires a stack, but I know no implementation which don't use any stack. AFAIU,C99标准规范中没有任何内容完全需要堆栈,但我知道没有任何实现不使用任何堆栈。

So of course, you can call foo in a loop within main . 所以当然,你可以在main中循环调用foo

I suggest to compile your code with all warnings and debug info (eg gcc -Wall -g ) and to use the debugger (eg gdb ) to run your program step by step and display the address of i 我建议使用所有警告和调试信息(例如gcc -Wall -g )编译代码,并使用调试器(例如gdb )逐步运行程序并显示i的地址

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM