我想创建一些连续的内存,并使用一堆指向它们的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指向它们中的每一个,然后释放第一个元素时,不会一起释放整个内存吗?
答案 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.