在C ++中删除堆栈变量

时间:2011-06-16 19:54:03

标签: c++ variables scope stack

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

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

6 个答案:

答案 0 :(得分: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(我按顺序思考,但我不知道标准是否强制要求)

此时,最终只有myVector仍在范围内的catch处理程序。该块忽略该异常,然后main结束 - 在该点myVector被破坏。

答案 1 :(得分:3)

根据 3.7.2 具有自动存储持续时间的对象,直到退出创建它们的块 6.6中有更多详细信息。 2

  

退出范围(但已完成)时,将为所有构造对象调用析构函数(12.4)   在该范围内声明的自动存储持续时间(3.7.2)(命名对象或临时对象)   相反的声明顺序。从循环中转出,从块中转出,或者从已初始化的变量返回   具有自动存储持续时间涉及销毁具有自动存储持续时间的变量   在从转移到的地点而不是在转移到的地点处的范围。

答案 2 :(得分:2)

当它超出范围时会被销毁。与C相同。

答案 3 :(得分:2)

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

答案 4 :(得分:0)

为了避免与new运算符的歧义,在离开函数时可能更适合说变量“弹出”:请参阅stack-based memory allocation。C也是如此。

答案 5 :(得分:0)

堆栈变量或多或少是通过递减堆栈指针从堆栈中削减的几个字节,它在函数末尾被删除,但是,不是简单地再次向上移动堆栈指针(用户的情况)在C ++中定义的类型)因为额外的破坏。

在C中,移动堆栈指针以摆脱所持有的变量是一个简单的例子。