【问题标题】:auto-memory management for pointers of pointers指针指针的自动内存管理
【发布时间】:2016-05-13 17:49:12
【问题描述】:

有些遗留函数需要动态数组 A**。例如,

A** array = new A*[100];
foo(array, 100);
...

void foo(A** a, int len) {
   for(int i=0;i<len; ++i) {
     a[i] = A::create(...);
   }
}

我想知道是否可以使用任何“智能”指针来管理这个数组。

我可以使用 boost::scoped_array 数组。它的 array.get() 返回 A**,因此它可以与遗留函数一起使用。但我认为数组的析构函数只释放顶级指针,而没有释放二级指针。

ptr_vector 自动删除所有内容。但它没有办法返回 A**。

我们还有其他解决方案吗?

【问题讨论】:

  • 你所说的这种遗留功能的一个例子会让这个问题更容易回答。
  • 有几种不同的方法可以实现通过双指针处理的动态二维数组。不同的需要不同的处理。
  • @AviBerger 有没有我们可以用来创建二维数组的 boost 或 stl 容器?
  • (续)在某些情况下,您可以使用 user2079303 的使用向量的建议,但如果 API 用于按照您的示例的建议创建行,这将不起作用。用于在构建矩阵期间处理错误/异常的显式代码,然后将其交给带有自定义删除器的 std::unique_ptr 可能在其他情况下也有效。如果打包到类中,这些中的任何一个都会更干净。
  • 我写了我的答案,假设您正在处理指向数组的指针数组(这是您通常使用T** 指针所拥有的)。如果我的回答不适合你的情况,那么你应该展示如何手动删除内部指针,以便我们可以展示如何自动删除。

标签: c++ memory-management boost


【解决方案1】:

如果 API 使用像 A::create(...) 这样返回指针的调用来创建对象,那么 API 肯定有一个互补调用来销毁像 A::destroy(ptr) 这样的对象。在这种情况下,以下自定义删除器应该是合适的:

std::unique_ptr<A*, void(*)(A**)> array_ptr(
    new A*[100],
    [](A** ptr) {
        for(std::size_t i = 0; i < 100; i++)
            A::destroy(ptr[i]);
        delete[] ptr;
    }
);
foo(array_ptr.get(), 100);

编辑我重写了我的答案,因为第一个版本似乎已经过时了。

【讨论】:

  • 使用这样的向量是个好主意。 OP 添加到他的帖子中的代码示例表明,至少整行甚至整个矩阵都构建在 API 的另一侧,因此在此用例中可能不起作用。您提到的某些版本的矩阵类可能是必要的。
  • @AviBerger 实际上,现在我看了一下,外部数组甚至可能不包含指向数组的指针,而是指向单个对象(由 API 创建)。
  • 这个解决方案很好,虽然我们必须这样做 (array_ptr.get())[i].
猜你喜欢
  • 2015-05-19
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
  • 1970-01-01
相关资源
最近更新 更多