2011-06-16 68 views
2

在C++中,如果我们在一个函数内部声明一个堆栈变量,它会在函数结尾自动删除还是在程序执行结束时被删除?在C++中删除堆栈变量

此外,这个问题的答案是相同的C语言?

回答

6

堆栈声明的变量,析构函数被调用并且内存回收,因为它超出了范围。

请注意,如果变量是在内部块中声明的,如if语句或循环,这并不意味着函数结束。

int main(int argc, char **argv) 
{ 
    int a = 3; 

    if (argc > 1) 
    { 
     int b = 5; 
     ++b; 
    } // b is destructed here 

    // a is destructed here 
    // argv and argc are destructed here (or with a) 
} 

编辑:良好有人提出的事实,也无所谓的范围是如何退出。所以...

#include <vector> 
# include <exception> 

int main(int argc, char **argv) 
{ 
    std::vector<int> myVector(10); 

    try 
    { 
     if (argc) 
     { 
      int a = 10; 
      int b = 12; 
      for (int c = 0; c < b; c++) // lol 
      { 
       int c_squared = c*c; 
       int theEleventhElement = myVector.at(c); 
       // the above will throw std::out_of_range at some point! 
      } 
     } 
    } 
    catch (std::out_of_range &ex) 
    { 
     // do nothing 
    } 
} 

当上述抛出时,堆栈将作为异常处理的一部分展开。由此,变量将按照以下顺序被破坏:

  • c_squared
  • c
  • ba(我想按照这个顺序,但如果这是在标准规定的,我不知道)

在这一点上,还有最后一个catch处理程序只有myVector仍然在范围内。该块忽略异常,然后main结束 - 在这一点myVector被销毁。

+1

是的,我知道“破坏”不是一个字。 :-P – 2011-06-16 19:58:34

+0

编辑添加一些关于异常的信息(受lccarrasco的引用标准答案的启发)。原谅我,如果我的STL知识虽然有点生疏! :-) – 2011-06-16 20:34:11

+0

真棒的答案。真的很清楚额外有趣的情况XD – rrazd 2011-06-16 20:45:01

2

它在超出范围时被销毁。 C相同。

+0

由于C没有“破坏”的概念,变量的内存只是被回收并且不再有效地访问。 – 2011-06-16 20:33:06

2

自动变量在封闭范围的末尾自动销毁。

0

为了避免与new运营商的模糊性,它可能是更合适地说,变量“弹出”,留下一个函数:看stack-based memory allocation。同样也适用于C.

0

堆栈变量或多或少是通过递减堆栈指针来削减堆栈中的几个字节,它在函数结束时被删除,但不是简单地再次移动堆栈指针(用户的情况 - 定义类型)在C++中,因为额外的销毁东西。

在C中,这是向上移动堆栈指针以摆脱所持有的变量的简单情况。

3

作为每3.7.2对象具有自动存储持续时间最后直到它们被创建块的出口处,有更多的细节在6.6.2

退出时从范围(然而完成),析构函数(12.4)被调用所有构造的对象与 自动存储的持续时间(3.7。2)(名称对象或临时对象)在该范围内声明,其声明的反向顺序。从一个循环中移出一个块,或者回到一个已初始化的变量 上,自动存储持续时间涉及销毁具有自动存储持续时间的变量, 在范围内,但是不在传输到的点上。