C ++使用shared_ptr连续分配内存

时间:2018-08-03 06:12:23

标签: c++

我想创建一些连续的内存,并使用一堆指向它们的shared_ptr。

int main() {
  int *arr = new int[5];
  for (int i = 0; i < 5; i++) {
    std::shared_ptr<int> ptr(&arr[i]);
  }// when the loop scope end, the shared_ptr will be destroyed. 
};

此代码将给出错误:

pointer being freed was not allocated

我的期望:当循环的范围结束时,shared_ptr将被销毁,而数组中的元素将被相继销毁。

但是,当第一个指针被破坏时,整个数组将被释放。

我也尝试过std::allocator,但仍然无法正常工作。

那么有什么方法可以分配连续的内存,我可以使用shared_ptr指向它们中的每一个,然后释放第一个元素时,不会一起释放整个内存吗?

2 个答案:

答案 0 :(得分:4)

这是一件很有趣的事情,但是如果您真的想做,可以使用shared_ptr的别名构造器。

int main() {
  std::shared_ptr<int[]> arr(new int[5]);
  for (int i = 0; i < 5; i++) {
    std::shared_ptr<int> ptr(arr,&arr[i]);
  }
};

没有c ++ 17,您需要做更多一点:

int main() {
    std::shared_ptr<int[]> arr(new int[5], std::default_delete<int[]> {});
    for (int i = 0; i < 5; i++) {
        std::shared_ptr<int> ptr(arr, &arr.get()[i]);
    }
};

当最后一个元素shared_ptr被销毁时(假设数组shared_ptr本身已经被销毁/重置),该数组将被删除。

答案 1 :(得分:3)

您滥用shared_ptr。您分配的内存是用operator new[]分配的,因此应该用operator delete[]释放它。

此外,由于分配的对象是一个数组,因此任何所有权语义都应应用于整个数组,而不是跨其元素划分!

您可以通过为shared_ptr指定自定义删除器来实现:(C ++ 11/14)

std::shared_ptr<int> arr_ptr(new int[5], std::default_delete<int[]> {});

或者仅使用shared_ptr(C ++ 17)的数组类型特化:

std::shared_ptr<int[]> arr_ptr(new int[5]); // Will call delete[] upon destruction.