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

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

在C中,大括号是作为一个堆栈框架吗?

C ++堆栈和范围

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

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

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


我能做些什么来确保局部变量保留在原位?

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

将访问者分配给局部变量足以确保他们不会被重用?

是。

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

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

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

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

它可以保证walker会在访问者之前被销毁,所以即使在析构函数中也不会包含任何悬挂引用。


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

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

链接地址: http://www.djcxy.com/p/84325.html

上一篇: Life span of stack allocated data in c++

下一篇: K&R C while loop omitting braces