遍历unique_ptr拥有的内存会导致段错误
为了不用记住删除,我们使用unique_ptr来管理内存。我们的印象是我们可以在内存中写入和读取,只是删除取决于智能指针。但是,以下代码在 i=7220 上崩溃并出现段错误。
怎么了?
#include <memory>
using namespace std;
int main() {
const uint32_t n = 40000000;
uint64_t*p = new uint64_t[n]; // this works, but we have to delete the memory or leak
for (int i = 0; i < n; i++)
p[i] = i;
unique_ptr<uint64_t> mem = make_unique<uint64_t>(n);
uint64_t* p1 = mem.get();
for (int i = 0; i < n; i++) // this crashes at i=7220
p1[i] = i;
return 0;
}
回答
unique_ptr<uint64_t> mem = make_unique<uint64_t>(n);
这将动态分配一个 uint64_t值n。
你要:
unique_ptr<uint64_t[]> mem = make_unique<uint64_t[]>(n);
unique_ptr<uint64_t[]> mem = make_unique<uint64_t[]>(n);
这种专业化分配一个阵列的uint64_t与n元件,并且具有一个operator[]过载这使得下面可能:
for (int i = 0; i < n; i++)
mem[i] = i;
所以,没有必要做 uint64_t* p1 = mem.get();
回答
unique_ptr<uint64_t>是指向单个uint64_t值的指针。为了使它存储一个数组,您需要使用未知绑定语法的数组:
要不就
auto mem{make_unique<uint64_t[]>(n)};
请注意,此变体重载了运算符 [],因此无需创建中间原始指针 uint64_t* p1 = mem.get();