这个简单的代码可以编译。
unique_ptr<list<int>> map1(new list<int>[10]);
但它在运行时会导致seg falut。
malloc: *对象0x7fe02a4032e8的错误:未释放指针被释放 * 在malloc_error_break中设置断点以进行调试
然而,此代码已成功运行。
unique_ptr<int> map2(new int[10]);
为什么无法使用unique_ptr创建列表数组?
提前致谢。
答案 0 :(得分:4)
您需要将unique_ptr版本用于动态分配的数组:
std::unique_ptr<std::list<int>[]> map1(new std::list<int>[10]);
^^ ~~~~~ !
见这里:http://en.cppreference.com/w/cpp/memory/unique_ptr:
template <
class T,
class Deleter
> class unique_ptr<T[], Deleter>;
您还可以使用std::make_unique(正如评论中所建议的),您将获得编译错误而不是UB,因为它的界面可以防止它:
std::unique_ptr<std::list<int>[]> up1 = std::make_unique<std::list<int>[]>(10);
auto up2 = std::make_unique<std::list<int>[]>(10);
[编辑]
然而,此代码已成功运行。
unique_ptr map2(new int [10]);
在上面的代码中它仍然是未定义的行为,它可能工作或可能导致seg错误。如上所述unique_ptr接受任何指针,但在构造期间始终会调用delete
。在指向动态分配的数组的指针上调用delete
是UB。这就是你需要调用delete[]
的原因,这就是动态分配数组的unique_ptr
。
答案 1 :(得分:1)
A list<int>
和list<int>[10]
是两种不同的类型。当你有
unique_ptr<list<int>>
您告诉unique_ptr
它将指向list<int>
。当unique_ptr
超出范围时,它将调用delete
来删除基础指针。不幸的是,你用
new list<int>[10]
需要使用delete []
而不是delete
删除。
unique_ptr<int> map2(new int[10]);
为什么第一个版本失败而第二个版本失败?:Undefined behavior。
在delete
编辑的内容上调用new[]
是未定义的行为
因此,如果您要在构造函数中使用new[]
,则需要使用type[]
作为unique_ptr
答案 2 :(得分:0)