2

在这个 C 代码片段中:

void func(void)
{
   int x=10;
   if (x>2)
   {
      int y=2;
      //block statement
      {
         int m=12;
      }
   }
   else
   {
      int z=5;
   }  
}

x,y,z 和 m 何时从 func 堆栈帧中分配和释放?

4

3 回答 3

2

实际分配取决于您的编译器,但许多编译器在函数开始时在堆栈上分配空间,并在函数返回之前释放它。请注意,这与变量实际可访问的时间是分开的,即直到定义它们的块的末尾。

在您的示例中,启用优化后,编译器可能不会在堆栈上为您的变量分配任何空间并简单地返回,因为它可以在编译时确定该函数实际上没有任何效果。

于 2012-10-17T12:52:34.333 回答
0

如果是自动变量(在代码块中声明的变量默认情况下是自动的),内存会在进入块时自动分配,并在退出块时自动释放(如果您使用 c 和 gcc)。您可以查看此来源此来源以获取更多信息。

于 2012-10-17T13:03:04.450 回答
0

根据 C++ 规则,您应该认为每个局部变量都在其块的末尾被销毁。这是调用析构函数的时间。但是,编译器可能会决定在函数的开头/结尾一起分配/取消分配所有局部变量,这就是 VC++ 编译器所做的:

void func(void)
{
001413B0  push        ebp  
001413B1  mov         ebp,esp  
001413B3  sub         esp,0F0h  
001413B9  push        ebx  
001413BA  push        esi  
001413BB  push        edi  
001413BC  lea         edi,[ebp-0F0h]  
001413C2  mov         ecx,3Ch  
001413C7  mov         eax,0CCCCCCCCh  
001413CC  rep stos    dword ptr es:[edi]  
    int x=10;
001413CE  mov         dword ptr [x],0Ah  

    if (x>2)
001413D5  cmp         dword ptr [x],2  
001413D9  jle         func+3Bh (1413EBh)  
    {
        int y=2;
001413DB  mov         dword ptr [y],2  
        //block statement
        {
            int m=12;
001413E2  mov         dword ptr [m],0Ch  
        }
    }
    else
001413E9  jmp         func+42h (1413F2h)  
    {
        int z=5;
001413EB  mov         dword ptr [z],5  
    }  
}

但这些是实现细节,编译器可以通过另一种方式自由调整堆栈指针。

因此,没有定义实际的堆栈指针调整,但构造函数/析构函数调用完全根据函数内部块完成。当然,您不能在其块之外使用变量 - 这不是编译的。尽管此时可能会分配堆栈空间。

于 2012-10-17T12:59:46.970 回答