【问题标题】:Deletion of stack variable in C++C++中栈变量的删除
【发布时间】:2011-09-16 16:37:00
【问题描述】:

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

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

【问题讨论】:

    标签: c++ variables scope stack


    【解决方案1】:

    它在超出范围时被销毁。 C 也一样。

    【讨论】:

    • 区别在于 C 没有“破坏”的概念,变量的内存只是被回收并且不再有效地访问。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        请注意,如果变量是在内部块(如 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 被破坏。

        【讨论】:

        • 是的,我知道“破坏”不是一个词。 :-P
        • 已编辑以添加一些有关异常的信息(受@lccarrasco 引用标准的回答启发)。如果我的 STL 知识有点生疏,请原谅我! :-)
        • 很棒的答案。非常有趣的案例也很清楚XD
        【解决方案5】:

        堆栈变量或多或少是通过减少堆栈指针从堆栈中删除的几个字节,它在函数结束时被删除,但是,不仅仅是再次向上移动堆栈指针(用户-定义类型)在 C++ 中,因为额外的破坏的东西。

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

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            猜你喜欢
            • 2015-05-14
            • 1970-01-01
            • 2011-06-29
            • 2011-04-13
            • 2021-12-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-06-10
            相关资源
            最近更新 更多