堆栈的生命周期在c ++中分配数据

时间:2013-05-07 07:57:08

标签: c++ variables optimization stack temporary

我的c ++代码在Debian(gcc(Debian 4.7.2-5)4.7.2)中正常工作,但在Ubuntu(gcc(Ubuntu / Linaro 4.7.2-2ubuntu1)4.7.2)中失败。我在变量之间重用堆栈空间,类似于这些问题中描述的内容:

In C, do braces act as a stack frame?

C++ stack and scope

除了我没有嵌套的范围。相反,代码看起来类似于:

TreeWalker walker;
walker.addVisitor(nodeType1, Visitor1());
walker.addVisitor(nodeType2, Visitor2());
...
walker.walkTree(tree);

我可以通过在堆上分配来缓解这个问题,但我想知道我该怎样做以确保本地变量保留在原位?将访问者分配给本地变量是否足以确保它们不会被重用?标准是否在最后一次使用函数代码后对堆栈变量提供了任何承诺?

2 个答案:

答案 0 :(得分:4)

  

我该怎样做才能确保保留局部变量?

使用(命名)局部变量,而不是临时变量;或修改addVisitor以存储访问者的副本,而不是对其进行引用,如果可行的话。

  

将访问者分配给本地变量是否足以确保它们不会被重用?

  

标准是否在最后一次使用函数代码后对堆栈变量提供了任何承诺?

Temporaries(在表达式中创建的未命名对象,例如您创建的访问者)一直存在,直到创建它们的完整表达式结束。所以它们一直持续到addVisitor的调用返回,但在下一行之前被销毁。

局部变量(在代码块中声明的自动变量)持续到程序离开声明它们的最内层块为止。当发生这种情况时,来自该块的每个局部变量将按其声明的相反顺序销毁。所以在下面:

{
    Visitor1 visitor1;
    Visitor2 visitor2;
    TreeWalker walker;
    walker.addVisitor(nodeType1, visitor1);
    walker.addVisitor(nodeType2, visitor2);
    //...
    walker.walkTree(tree);
}

保证walker将在访问者之前销毁,因此即使在析构函数中也不会包含任何悬空引用。

答案 1 :(得分:2)

Visitor1()不是局部变量,它是一个临时变量。临时的生命周期在它出现的完整表达结束时结束。

如果您需要保留它们,请使用局部变量代替临时变量。