删除C++中的堆栈变量

Deletion of stack variable in C++

本文关键字:堆栈 变量 C++ 删除      更新时间:2023-10-16

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

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

对于堆栈声明的变量,会调用析构函数,并在超出范围时回收内存。

请注意,这并不意味着在函数末尾,如果变量是在内部块中声明的,比如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)
}

EDIT:关于如何退出作用域并不重要这一事实,我们提出了一个很好的观点。所以…

#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被销毁。

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

在退出一个作用域时(但已完成),所有构造的对象都会调用析构函数(12.4)在该范围中声明的自动存储持续时间(3.7.2)(命名对象或临时对象)与他们声明的顺序相反。传出循环、传出块或返回经过初始化的变量具有自动存储持续时间涉及变量的销毁在从转移点的范围内,但在转移到的点不在范围内。

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

自动变量在其封闭范围结束时自动销毁。

为了避免new运算符的歧义,在离开函数时说变量是"弹出的"可能更合适:请参阅基于堆栈的内存分配。C.也是如此

堆栈变量或多或少是通过减少堆栈指针从堆栈中删除的几个字节,它在函数结束时被删除,但是,在C++中,由于额外的销毁内容,它并不是简单地再次向上移动堆栈指针(对于用户定义的类型)。

在C中,这是一种简单的情况,向上移动堆栈指针以清除所保留的变量。