在C中的for循环中,变量x会发生什么变化?

时间:2017-04-01 18:10:49

标签: c memory-management dynamic-memory-allocation static-memory-allocation

在下面的代码中

int main(){
int i;
for(i = 0;i<4;i++){
int x = 1;
x++;
} // for close
}// main close

这里变量x是`自动存储类,对吗?

那么,变量x是否会被创建,我的意思是内存分配在遇到语句时发生,当它到达循环结束时被破坏并且被创建/内存再次被分配给{{1} }?

我尝试在循环中打印x的地址,并且每次都为x打印相同的地址。所以,每次创建和销毁x并且它正在使用相同的房间/内存块吗?

如果它正在创建和破坏,那么它是否会影响CPU使用率? 如果是这样,有没有办法防止它并保持良好的记忆健康?

4 个答案:

答案 0 :(得分:2)

简短的回答是&#34;没有&#34;。任何优化编译器都会优化此变量,因为它永远不会被读取。

即使关闭优化器,变量也会在进入函数时分配一次,然后在每次迭代中设置为1,然后再增加。

分配非常便宜,因为它在自动存储中。这个空间是在编译时决定的,因此在运行时它不需要任何费用。所有迭代都重用相同的位置,因此迭代不会产生额外的成本。

答案 1 :(得分:1)

是的,为循环中的每个回合构造和销毁变量。

但是,正如您所注意到的,编译器足够智能,每次都可以为变量重用相同的存储。可能在堆栈上,在输入函数时可以分配空间。所以没有必要担心“内存管理”。

如果你打开一些优化,编译器也可能会注意到没有任何变量真正用于任何事情,并删除所有代码。

答案 2 :(得分:1)

它取决于实现。你看到相同的内存地址,因为编译器决定这样做。在每次迭代之前,内存并不是在新地址上神奇地分配。 x86体系结构中的自动存储是使用堆栈实现的,只需通过减去ESP / RSP(x86 / x64)寄存器来完成分配,该寄存器指向堆栈的顶部。您可以在互联网上阅读有关它的文章。

编译器只需每次迭代重新分配内存(不分配/解除分配)

这是您的代码的汇编列表(GCC 6.3,x86)。汇编语言中的注释以;开头。我添加了c像伪代码来解释指令的含义

main:
        push    ebp
        mov     ebp, esp ; Create new stack frame
        sub     esp, 16 ; Allocate memory for local variables
        mov     DWORD PTR [ebp-4], 0 ; i = 0;
.L3:
        cmp     DWORD PTR [ebp-4], 3  ; if(i > 3)
                                      ; {
        jg      .L2                   ;    break;
                                      ; }
        mov     DWORD PTR [ebp-8], 1 ; x = 1;
        add     DWORD PTR [ebp-8], 1 ; x += 1;
        add     DWORD PTR [ebp-4], 1 ; i += 1;
        jmp     .L3 ; Go to location .L3
.L2:
        mov     eax, 0 ; Set return value to 0
        leave ; Restore the stack pointer
        ret ; Return to the caller

因此ebp - 8(或int x)的地址每次都相同。

这是优化的代码汇编列表(GCC 6.3, - O3,x86)。

main:
        xor     eax, eax ; Set return value to 0
        ret ; Return to the caller

答案 3 :(得分:0)

在for循环的每次迭代中,您创建变量'x',将其设置为1,并将其递增为2.'x'正在被销毁,因为它仅存在于for循环中。如果您不希望每次迭代都创建和销毁它,您可以简单地在for循环上面声​​明它。

但是你想用这段代码完成什么呢?它似乎没有做太多。此外,由于你担心内存分配,变量'i'可以在for循环中声明,这样你就可以在完成for循环后没有它。