在从函数返回之前释放unique_ptr

时间:2011-12-28 21:13:12

标签: c++ visual-studio-2010 smart-pointers

我正在使用unique_ptrconst wchar_t指针传递给函数。在下文中,我想举一个简短的例子:

bool MyClass::foo(unique_ptr<const wchar_t> display_name) {
  bool result = false;
  ....
  // Do something
  result = DoWork(display_name.get());
  ....
  // I have to call release to prevent getting an error
  display_name.release();
  return result;
}

到目前为止,我认为在离开范围(从函数返回)之前我不必调用release()的{​​{1}}方法,因为unique_ptr的内容将自动生成如果unique_ptr超出范围,则删除。但如果不调用unique_ptr方法,我会收到以下错误(VS 2010):

enter image description here

我认为发生此错误消息是因为内存未正确释放?处理release()的推荐方法是什么,它作为参数传递?

2 个答案:

答案 0 :(得分:3)

根据您的描述和评论,我相信这更符合您的要求:

bool MyClass::foo(const std::wstring& display_name)
{
  bool result = false;

  // Do something
  result = DoWork(display_name.c_str());

  return result;
}

此字符串对象是wchar_t的STL容器,具有各种有用的方法。其中一个是c_str(),它返回字符串内容的c样式const wchar_t*版本,以便与旧代码向后兼容。你的DoWork函数可能是一个需要c风格字符串的函数,所以上面的函数适合你。


现在进入智能指针101:

在C ++ 11中,std::unique_ptr可用于自动销毁堆上分配的对象,免除异常不安全代码和手动内存管理的后顾之忧,这可能导致内存泄漏和其他不良内容。假设您有以下代码:

void LeakyFunction()
{
    double* ptr = new double;
}

显然这是一个内存泄漏,因为一旦LeakyFunction的范围结束,我们就丢失了堆栈上的指针,不再能删除它在堆上指向的内容。所以我们写这个:

void LessLikelyLeakyFunction()
{
    double* ptr = new double;
    // do stuff
    delete ptr; // clean up heap
}

除非你在代码的do stuff部分期间提前返回或抛出异常,否则你会回到同样的问题。所以人们开始编写自定义智能指针类,它通过分配构造和解除分配来破坏原始内存分配。现在,这个概念已成为std::unique_ptr之类的标准,因此我们可以执行以下操作:

void SmartFunction()
{
    std::unique_ptr<double> ptr(new double);
    // do stuff
} // unique_ptr is smart and calls delete for you

通过这种方式,无论何时功能范围结束,您都不必担心事情会被正确清理。 简而言之,如果您不使用new,则不需要智能指针,如果您是,那么您可能应该使用智能指针使代码更加健壮。

答案 1 :(得分:2)

通过unique_ptr,您试图在指向字符串文字常量的指针上调用delete

您必须只允许在指向使用delete创建的对象的指针上调用new