我看了一下,但找不到答案。
我有一个函数返回一对指向对象的指针,情况可以简化为:
#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:这个问题经过编辑,可以更好地说明问题,让我看起来更聪明!
答案 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()
,您永远不会从通话中泄漏内存。