c++ - 在我的代码中,scoped_ptr 指向一个堆栈变量——这会延长堆栈变量的生命周期吗?

标签 c++ pointers boost

我想知道下面的代码是否格式正确

 if (  nChildLines == 0 ) 
 {
    nChildLines = 1;
    Tag tempTag = attachmentlines.tag();
    cfgChildLines = &tempTag;
 }

这里,tampTag 是一些对象。 cfgChildLines 是指向在“if” block 之外声明的对象的作用域指针。

现在我的问题是,当“if” block 完成时,tempTag 会被破坏吗?如果是这样,指向 tempTag 的“cfgChildLines”的使用在 if block 结束后是否有效?

最佳答案

重要的是要记住,在 C++ 中获取地址并不能保证该地址继续指向有效内容的任何保护。语言中没有内置引用计数(这就是为什么我们必须发明 scoped_ptr/shared_ptr 等)。

牢记这一点,我们可以更详细地了解您的情况:

tempTag 是一个自动变量,在它创建的范围结束时被销毁。因此,您获取的地址将指向堆栈中某处指向此范围之外的已销毁对象。由于您分配给了一个 scoped_ptr,并且 scoped_ptr 假定它可以通过删除销毁对象,来自 the documentation

The scoped_ptr class template stores a pointer to a dynamically allocated object

(强调我的)

所以你违反了 scoped_ptr 的接口(interface),一旦 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)。您只能策略性地将这些变量放在正确限定变量范围的位置,以便自动的、基于堆栈的生命周期与您打算如何使用这些东西相对应。

关于c++ - 在我的代码中,scoped_ptr 指向一个堆栈变量——这会延长堆栈变量的生命周期吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7320122/

相关文章:

c++ - 为什么 boost::filesystem::path 返回路径而不是字符串

c++ - 在一个代码块中多次互斥锁定一个变量,还是只锁定整个代码块,效率更高?

c++ - MPI_Allreduce 加倍

visual-c++ - Visual C++ 非托管和托管

c - 在 C 中使用 malloc 动态创建一个二维指针数组

c++ - boost 参数库

c++ - 使用 Boost 列出文件夹中的文件时出错

c++ - 根据其他变量设置变量

c++ - 对类里面的 C++ 引用感到困惑

c - 函数 malloc 一个指针并将数据读入其中,但调用者无法访问它