我的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?
除了我没有嵌套的范围。相反,代码看起来类似于:
TreeWalker walker;
walker.addVisitor(nodeType1, Visitor1());
walker.addVisitor(nodeType2, Visitor2());
...
walker.walkTree(tree);
我可以通过在堆上分配来缓解这个问题,但我想知道我该怎样做以确保本地变量保留在原位?将访问者分配给本地变量是否足以确保它们不会被重用?标准是否在最后一次使用函数代码后对堆栈变量提供了任何承诺?
答案 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()
不是局部变量,它是一个临时变量。临时的生命周期在它出现的完整表达结束时结束。
如果您需要保留它们,请使用局部变量代替临时变量。