在我的代码中,scoped_ptr指向一个堆栈变量 - 这是否延长了堆栈变量的生命周期
In my code scoped_ptr points to a stack variable -- does that extend the lifetime of the stack variable?
我想知道以下代码的格式是否正确
if ( nChildLines == 0 )
{
nChildLines = 1;
Tag tempTag = attachmentlines.tag();
cfgChildLines = &tempTag;
}
在这里,tampTag是一些对象。cfgChildLines是一个作用域指针,指向在"if"块之外声明的那个对象。
现在我的问题是,当"if"块完成时,tempTag会被破坏吗?如果是这样,指向 tempTag 的"cfgChildLines"的使用是否在 if 块结束时有效?
重要的是要记住,在C++中获取地址并不能保证该地址继续指向有效内容的任何保护。语言中没有内置的引用计数(这就是为什么我们必须发明scoped_ptr/shared_ptr/等(。
请记住这一点,我们可以更详细地了解您的情况:
tempTag
是一个自动变量,在创建它的作用域结束时被销毁。因此,您获取的地址将指向堆栈上的某个位置,指向此范围之外的已销毁对象。由于您分配给了scoped_ptr,并且scoped_ptr假定它可以通过删除来销毁对象,因此从文档中
scoped_ptr类模板存储指向动态分配对象的指针
(强调我的(
因此,您违反了scoped_ptr的接口,一旦删除scoped_ptr,您将有一些未定义的行为。
{
nChildLines = 1;
Tag tempTag = attachmentlines.tag();
cfgChildLines = &tempTag;
} // tempTag destroyed here
// LATER
} // scoped_ptr calls delete, undefined behavior possibly crash,
// possibly an occasional crash
如果你确实需要在更大的范围内使用 tempTag,那么只需在你需要它的更大范围内声明它,不要使用 scoped_ptr。
void Foo()
{
Tag tempTag
{
nChildLines = 1;
tempTag = attachmentlines.tag();
}
}
另一种思考方式:当您创建动态分配的对象时,您将拥有其生存期的所有权。您手动创建和销毁该事物。因此,您可以将此所有权传递给另一个对象,例如可以为您管理事物的scoped_ptr。相比之下,在堆栈上创建的变量将自动分配和取消分配 - 创建和销毁的权限完全由调用堆栈持有,您不能将这些权限授予您自己或其他人(即scoped_ptr(。您只能战略性地将这些变量放置在正确限定变量范围的位置,以便基于堆栈的自动生命周期与您打算如何使用该事物相对应。
是的,因为tempTag
对象在if
结束时超出范围时被销毁,所以在if
之后,cfgChildLines
会指向一个被破坏的对象。
您可以使用new
来修复此问题,只需对现有代码进行最少的修改:
if ( nChildLines == 0 )
{
nChildLines = 1;
Tag* tempTag = new Tag(attachmentlines.tag());
cfgChildLines = tempTag;
}
然后在if
之后,cfgChildLines
指向一个有效的Tag
,当它超出范围时被销毁。
同样正如 Node 指出的那样,永远不要在未由 new
分配的东西上使用智能指针。在您的示例中,您使智能指针指向堆栈分配的对象,即使它具有更长的生存期,该对象也是无效的,因为当智能指针超出范围时,它将尝试delete
堆栈分配的对象并导致未定义的行为。
你问:
"指向 tempTag 的'cfgChildLines' 的使用是否在 if 块末尾有效?">
不,当然是无效的。你有 UB。别这样了。
注意:SO版主比尔蜥蜴删除了我之前的回答,实际上是相同的,大概是因为他认为他知道得更多。
目前接受的"解决方案"是不正确的,这个答案是正确的。
Word更正地理(将"东北"更改为"西北"(和SO mods纠正技术内容真的很烦人。
- 堆栈中大小变量输入错误 (C++)
- 变量周围的堆栈'...'已损坏
- 在 gtest 中初始化堆栈上的引用变量的隔离错误
- 运行时检查失败 #2 变量"A"周围的堆栈已损坏
- 如果我们通过引用传递变量,则递归中使用的堆栈空间量是否为零?
- 在 c++ 中确定堆栈上的变量范围
- 为什么在堆栈和堆上创建变量会产生相同的程序集代码?
- 为什么弹出我的堆栈会返回垃圾而不是初始变量?
- 堆栈粉碎 在我在代码中添加新变量以及一些操作后C++检测到
- 无法在具有常量变量大小的类中创建堆栈分配数组
- 运行时检查失败 #2 - 变量"e"周围的堆栈已损坏。发生
- 堆栈/帧指针作为外部变量
- "new"创建的实例的所有成员变量是否都存在于堆上而不是堆栈上?
- 变量周围的堆栈'sortArray'已损坏
- 堆栈变量超出范围时是否解除分配?
- 变量周围的堆栈'folderPath'已损坏
- 何时在函数中声明堆栈分配变量?
- 运行时检查失败 #2 - 变量周围的堆栈'...'已损坏
- C++ 大于堆栈的变量(堆栈溢出)
- 局部变量堆栈