当我获得指向智能指针的指针时,是否必须释放内存?

dwn*_*enr 1 c++ smart-pointers c++11

我目前正在学习新的c ++内容,而我目前正在学习使用智能指针(std::unique_ptr).

可以说,我有一个std::vectorstd::unique_ptr.在我的代码中的某一点,我需要迭代这个stl向量并挑选出我需要计算的对象.

  for (const auto& obj : objectList)
  {
    if(/*check if this is an object I need*/)
      OtherFunc(obj.get());
  }

  void OtherFun(object* obj)
  {
     std::vector tempVector.push_back(obj);
  }
Run Code Online (Sandbox Code Playgroud)

在OtherFunc中,我将这个作为参数传入的对象添加到另一个std::vector(表示为otherVector),我保留并进行计算.我不希望OtherFunc拥有对象的所有权.我只需要保留它们,所以我不必每帧传递对象.

我知道如果智能指针离开作用域(或者在我的情况下,退出程序)将自行解除分配,包含智能指针对象的对象 otherVector会发生什么.我试着在cplusplus.com查看文档,但我无法得到我的问题的答案.我是否必须取消分配我在otherVector中保存的所有对象?或者由于对象最初是智能指针,我可以假设otherVector中的所有指针也将变为null(因此,不会导致内存泄漏).

chr*_*ris 8

get()will的文档将声明它只返回一个指向托管资源的非所有者指针,而不是release()实际将所有权转移到返回的指针.

这足以回答你的问题,你不应该清理那个指针.但是,还有其他一些需要注意的问题.

首先,你必须对生命保持谨慎.管理资源仍然是智能指针的工作.如果智能指针清理,则原始指针将悬空.确保智能指针超过原始指针.如果你不能这样做,你应该使用shared_ptr,这确保只有在完成所有相关的智能指针后才清理资源.

现在有两种方法可以shared_ptr用于此任务.两者都需要更改原始向量中的智能指针的类型shared_ptr.在前言中,假设您正在使用此指针并将其存储以供以后使用.当它被使用时,原始矢量可能会消失,其中的智能指针随之消失.我还假设您需要一个原始指针来执行您对资源执行的操作.也许您需要将它赋予C函数.

  1. 直接使用它.如果您希望资源至少与OtherFun用于需要的资源一样长,那么这是很好的.OtherFun将采用a shared_ptr,现在可以通过直接传递vector元素而不使用来创建get.

    get事实上,在这里使用会导致错误,因为shared_ptr需要从另一个构造错误shared_ptr,以便对资源进行适当的引用计数.OtherFun存储shared_ptr在任何需要它和存储的指针确保资源不会在原始向量时死亡.

    当需要访问资源时,您可以从中获取所需的原始指针,shared_ptr并确保本地shared_ptr比使用此原始指针更长,这比确保它比矢量元素更容易.

  2. 商店weak_ptr.如果您希望原始向量是唯一负责资源的向量,但是需要能够检查资源是否仍然有效并且如果是,则使用它.OtherFun将存储weak_ptr在任何需要它.如果原始矢量死亡,资源也会.

    当需要从其他地方使用资源时,shared_ptrweak_ptr使用lock(给出可能为空shared_ptr)或shared_ptr转换构造函数weak_ptr(抛出可能的异常)获得a.您可以适当地检查资源是否仍然存在,并shared_ptr确保它将保留在那里直到您完成.此时,您可以继续选项1并获取所需的原始指针.

除了所有这些,你必须小心所有权.来自的原始指针get()绝不能变成任何类型的所有者.例如,以下是错误的,将导致指针的双重删除:

void OtherFun(object* obj)
{
    std::unique_ptr<object> p(obj);
}
Run Code Online (Sandbox Code Playgroud)

在这里,你给的唯一所有权*objp,即使unique_ptr你打电话get()仍然拥有*obj.这类似于前面提到的shared_ptr::get()陷阱,最终会有两个无关联的shared_ptrs管理相同的资源.

get()本质上是不安全的,打破了封装.但是,为了实际使用智能指针,智能指针也是必要的.请注意,您可以陷入陷阱,无论是从获取原始指针的生命周期,还是最终将非拥有的原始指针转换为所有者.这就是该release()功能的用途.通常,当您不需要来自智能指针的原始指针以及仅将原始指针视为非所有者时,您会更加安全.