将函数返回的一对原始指针分配给unique_ptr

时间:2014-11-28 10:25:45

标签: pointers c++11 smart-pointers

我看了一下,但找不到答案。

我有一个函数返回一对指向对象的指针,情况可以简化为:

#include <iostream>
#include <utility>
#include <memory>

std::pair<int *, int *> shallow_copy()
{

   int *i = new int;
   int *j = new int;

   *i = 5;
   *j = 7;

   return std::make_pair(i, j);
}

int main(int argc, char *argv[])
{
   std::pair<int *, int *> my_pair = shallow_copy();

   std::cout << "a = " << my_pair.first << " b = " << *my_pair.second << std::endl;

   // This is just creating a newpointer:
   std::unique_ptr<int> up(my_pair.first);

   std::cout << "a = " << &up << std::endl;

   delete my_pair.first;
   delete my_pair.second;

   return 0;
}

我无法更改函数的返回值。从std::cout << "a = " << &up << std::endl;我可以看到智能指针的地址与原始指针的地址不同。

有没有办法在std::pair中捕获函数返回的std::unique_ptr,并在不明确调用delete的情况下防止内存泄漏?

NB:这个问题经过编辑,可以更好地说明问题,让我看起来更聪明!

1 个答案:

答案 0 :(得分:2)

你以正确的方式做到了,但是测试错了。您正在将 first中的地址与 up的地址进行比较。如果您改为打印up.get() <{em> up中存储的地址),您将发现它们相等。

此外,您的代码有双重删除问题。您执行delete my_pair.first;,它会释放my_pair.first指向的内存块以及up。然后,当up超出范围时,up的析构函数将再次释放它,从而导致双重删除。

您还询问了如何捕获智能指针中的两个指针。由于std::unique_ptr的构造函数采用原始指针是显式的,因此您不能使用简单的std::pair<std::unique_ptr<int>, std::unique_ptr<int>>直接执行此操作。但是,您可以使用辅助函数:

std::pair<std::unique_ptr<int>, std::unique_ptr<int>> wrapped_shallow_copy()
{
  auto orig = shallow_copy();
  std::pair<std::unique_ptr<int>, std::unique_ptr<int>> result;
  result.first.reset(orig.first);
  result.second.reset(orig.second);
  return result;
}

现在,使用wrapped_shallow_copy()代替shallow_copy(),您永远不会从通话中泄漏内存。