在C ++中,如果我们在函数内部声明一个堆栈变量,它是在函数末尾自动删除还是在程序执行结束时删除?
此外,对于 C 语言,这个问题的答案是否相同?
答案 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
b
和a
(我按顺序思考,但我不知道标准是否强制要求)此时,最终只有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中,移动堆栈指针以摆脱所持有的变量是一个简单的例子。