c+中堆栈分配数据的生命周期+; 我有C++代码,在Debian(GCC(Debian 4.7.2-5)4.7.2)中工作正常,但在Ubuntu(GCC(Ubuntu/LimARO4.7.2-2Ubuntu1)4.7.2)中失败。我得到了变量之间重用的堆栈空间,类似于这些问题中所描述的:

c+中堆栈分配数据的生命周期+; 我有C++代码,在Debian(GCC(Debian 4.7.2-5)4.7.2)中工作正常,但在Ubuntu(GCC(Ubuntu/LimARO4.7.2-2Ubuntu1)4.7.2)中失败。我得到了变量之间重用的堆栈空间,类似于这些问题中所描述的:,c++,variables,optimization,stack,temporary,C++,Variables,Optimization,Stack,Temporary,除了我没有嵌套的作用域。相反,代码与此类似: TreeWalker walker; walker.addVisitor(nodeType1, Visitor1()); walker.addVisitor(nodeType2, Visitor2()); ... walker.walkTree(tree); 我可以通过在堆上进行分配来缓解这个问题,但我想知道如何确保局部变量保持不变?将访问者分配给局部变量是否足以确保它们不会被重用?在函数代码中最后一次使用堆栈变量之后,standard是否对其提供

除了我没有嵌套的作用域。相反,代码与此类似:

TreeWalker walker;
walker.addVisitor(nodeType1, Visitor1());
walker.addVisitor(nodeType2, Visitor2());
...
walker.walkTree(tree);
我可以通过在堆上进行分配来缓解这个问题,但我想知道如何确保局部变量保持不变?将访问者分配给局部变量是否足以确保它们不会被重用?在函数代码中最后一次使用堆栈变量之后,standard是否对其提供了任何承诺?

Visitor1()
不是局部变量,而是临时变量。临时对象的生存期在其出现的完整表达式结束时结束

如果需要保留它们,请为它们使用局部变量,而不是临时变量

如何确保局部变量保持不变

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

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

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

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

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

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

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

如果不知道
addVisitor
的功能(例如,它是否复制了第二个参数?),则无法确定临时变量(或其副本)的寿命在OP的代码中是。尽管如此,他描述的行为似乎指向不复制,这似乎是错误的做法。@rubenvb没有任何东西可以影响这些表达式中临时人员的寿命。它们拷贝的生存期(如果有的话)完全是另一回事,但它丝毫不会影响调用函数的“堆栈帧”。这都是事实,但通常不是问题。这表明
Visitor
类的复制构造函数没有值语义,也就是说它没有将状态临时正确地复制到树节点中(当
addVisitor
请求时)。@rubenvb而OP没有明确地这样说,他选择的名称和示例代码清楚地表明,
Vistor1
Visitor2
是同一基础的多基因实例。因此,
TreeWalker
无法真正复制它们(除非有额外的限制,例如存在
clone
功能)。逻辑上,它不会复制它们,因为副本需要动态分配。“我有C++代码,它工作正常”如果你的程序依赖于在同一个位置上不创建的临时文件,那么它就不能正常工作,它有时看起来只是正常工作。您有一个应该修复的bug,而不是解决的bug。