c++中栈分配数据的生命周期
Life span of stack allocated data in c++
我有c++代码在Debian (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);
我可以通过在堆上分配来缓解这个问题,但我想知道我能做些什么来确保局部变量留在原地?将访问者分配给局部变量是否足以确保它们不会被重用?标准是否在函数代码中最后一次使用堆栈变量后提供任何承诺?
我能做些什么来确保局部变量留在原地?
使用(named)局部变量,而不是临时变量;或者修改addVisitor
以存储访问者的副本,而不是对它的引用,如果可行的话。
将访问者分配给局部变量是否足以确保它们不会被重用?
是的。
标准是否在函数代码中最后一次使用堆栈变量后提供任何承诺?
临时(在表达式期间创建的未命名对象,例如您创建的访问者)一直存在,直到创建它们的完整表达式结束。因此,它们一直持续到对addVisitor
的调用返回,但在下一行之前被销毁。
局部变量(在代码块中声明的自动变量)一直持续到程序离开声明它们的最内层块。当这种情况发生时,该块中的每个局部变量将按照声明的相反顺序销毁。所以在下面的语句中:
{
Visitor1 visitor1;
Visitor2 visitor2;
TreeWalker walker;
walker.addVisitor(nodeType1, visitor1);
walker.addVisitor(nodeType2, visitor2);
//...
walker.walkTree(tree);
}
保证walker
会在访问者之前被销毁,所以即使在析构函数中也不会包含任何悬垂引用
Visitor1()
不是一个局部变量,它是一个临时变量。当出现临时对象的完整表达式结束时,临时对象的生存期结束。
如果你需要保存它们,使用局部变量代替临时变量。
相关文章:
- 如何在共享库的整个生命周期内存储数据
- 如何理解句子的生命周期始于对e的评估
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了
- Go/C++gRPC客户端通道和存根生命周期
- 如何将"this"的生命周期移动到C++中的另一个对象中?
- 是否可以通过使用移动/交换 c++11 来延长返回的临时变量的生命周期
- 使用对象的生命周期作为设置器的安全性
- 临时人员的生命周期传递给函数
- 我想知道在构造函数中初始化变量时的生命周期
- Lua 用户数据生命周期管理
- 如何使用 epoll(void* event.data.ptr) 管理 Connection 的生命周期
- C++引用的生命周期
- 在堆栈上有一个对象,而不是在函数的整个生命周期内
- 在 Boost ASIO 服务器中处理生命周期
- C++ lambda 生命周期
- 使用互斥锁跟踪另一个应用的生命周期
- QSharedPointer 或 std::shared_ptr 的生命周期
- 来自async_resolve的 boost::asio::ip::tcp::resolver::iterator 的生命周期是多久?
- 如何调整属于类的唯一指针的字符数组的大小.它必须在程序的整个生命周期中保持活力
- 延长 std::tuple<int&,int> 的生命周期,方法是将其分配给 const std::tuple<int, int>&