使用智能指针管理在函数内分配的内存

5

背景

如果我有一个如下的函数foo

void foo(std::vector<int>& values)
{
    values = std::vector<int>(10, 1);
}

然后我可以将其称为:
std::vector<int> values;
foo(values);

请注意,初始的vector为空,然后在函数foo中填充。

我经常遇到无法更改的接口(即第三方接口),它们具有与上述相同的意图,但使用原始数组,例如

void foo(int*& values)
{
    values = new int[10];
    std::fill_n(values, 10, 1);
}

我的问题是现在我需要负责管理这些内存,例如:

int* values;
foo(values);
delete[] values;

问题

有没有办法使用智能指针来管理我的内存?我想做类似这样的事情:

std::unique_ptr<int[]> values;
foo(values.get());

但是 get 返回的是一个 r-value 指针,所以我不能通过非 const 引用传递它。


1
我不知道这是否合法,但它确实可以编译:http://coliru.stacked-crooked.com/a/860ae38fd2cdb4a2 - NathanOliver
2个回答

2
  1. 创建一个空的unique_ptr。
  2. 创建指针。
  3. 将指针传递给函数。
  4. 将unique_ptr重置为该指针。

就像这样:

std::unique_ptr<int[]> values;
int* values_ptr;
foo(values_ptr);
values.reset(values_ptr);

或者:

int* values_ptr;
foo(values_ptr);
std::unique_ptr<int[]> values(values_ptr);

事实上,make_unique会自己构建对象,你不能给它一个指针,或者说你可以吗? - Gabriel

1
简单回答:你不能。 但我相信有一种方法可以简化你的生活。由于你总是做同样的事情,你只需要编写一个函数来代替你,并在需要时调用该函数。由于我假设你想在释放内存之前使用写入的返回值,所以我的函数会将其返回。
template <typename T, typename Function>
std::unique_ptr<T[]> call(Function f) {
  T * value;
  f(value);
  return { value };
}

// then to use it
auto value = call<int>(foo);

你觉得这样行吗?

如果需要,该函数可以改进以检测指向一个对象或数组的指针之间的差异,并且可能还可以自动检测所需的参数类型,以便您不必输入它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接