C ++中goto语句对堆栈的影响

时间:2014-11-08 14:27:43

标签: c++ stack-overflow goto destroy callstack

在C ++中执行goto语句时,下面的代码片段中的两个数组是否已从堆栈中删除?或者,当方法返回时,它们是否会从堆栈中删除?

retrySplit:
    ...
    uint32_t primsAbove[primitives.size()];
    uint32_t primsBelow[primitives.size()];
    ...
    goto retrySplit;

此问题与使用goto语句导致的泄漏无关,但与是否可能炸毁堆栈有关。

3 个答案:

答案 0 :(得分:5)

是的,阵列被破坏了。 [stmt.jump] / 2:

  

退出范围(无论多么已完成),具有自动对象   在该范围内构建的存储持续时间(3.7.3)   按其建造的相反顺序销毁。 [...] 转移   一个循环,一个块,或返回一个初始化变量   自动存储持续时间涉及对象的破坏   在转移点范围内的自动存储持续时间   从而不是转移到。

您还可以通过以下代码段验证这一点:

#include <iostream>

struct A
{
    A() {std::cout << "A";}
    ~A() {std::cout << "D";}
};

int main()
{
    int counter = 0;

    label:
        if (counter++) // Exit on second run. 
            return 0;

        A a;
        goto label;
}

Demo。您的输出应为AD。 另请注意,跳回counter时,label不会被销毁。

答案 1 :(得分:5)

这个程序:

#include <iostream>

class X {
public:
 X() { std::cout << "ctor" << std::endl; }
 ~X() { std::cout << "dtor" << std::endl; }
};

int main(int argc, char** argv) {
 int i = 0;

label:
 X a;

 if (i == 0) {
  i = 1;
  goto label;
 }

 return 0;
}

生成此输出:

$ ./a.out 
ctor
dtor
ctor
dtor

答案 2 :(得分:1)

从堆栈中移除并活着是两回事。在您的示例中,可以保留堆栈中用于数组的内存,但是在跳转到lable之后,数组将被视为不活动。那是在调用数组元素的跳转析构函数之前,当控件在数组的构造函数中实现数组的定义时。元素将被调用。