正确unique_ptr 1 个元素分配数组的声明

Proper unique_ptr declaration of 1 element allocated array

本文关键字:分配 数组 声明 元素 unique ptr 正确      更新时间:2023-10-16

我需要将 API 用作项目的一部分,该项目包含一个名为ParamSet的类,其方法定义如下:

void AddString(const std::string &, std::unique_ptr<std::string[]> v, int nValues);

该方法的目的是向对象添加一个字符串数组来描述某个参数。例如,ParamSet对象可能需要指向nValues字符串数组的"文件名"参数。

但是,当我尝试将方法unique_ptr传递给仅包含 1 个字符串的数组时,代码 seg 在调用ParamSet对象的析构函数时出错,除非我以特定方式定义unique_ptr

以下代码在调用Clear()return时导致段错误。

ParamSet badparam;
badparam.AddString("filename", unique_ptr<string[]> (new string("test")), 1);
badparam.Clear(); // <------ CAUSES SEG FAULT

但是,以下情况不会导致 seg 故障。

ParamSet testparam;
std::unique_ptr<std::string[]> strings(new std::string[0]); // DOH, should be string[1]
strings[0] = std::string("test");
testparam.AddString("filename", std::move(strings), 1);
testparam.Clear(); // <------ NO SEG FAULT

我不明白为什么在调用AddString的线路中创建unique_ptr会导致 seg 错误,但在调用之外创建它则不然。

问题是您使用非数组new来分配由unique_ptr<T[]>管理的内存,然后这些内存将继续使用数组delete[],从而导致未定义的行为。

语法可以是:

badparam.AddString("filename", std::unique_ptr<std::string[]>(new std::string[1]{"test"}), 1);

std::unique_ptr的数组专用化要求数组分配new[],因为它默认使用delete[]来释放数组。

在第一个示例中,您分配的是带有new的单个std::string对象,而不是带有new[]的 1 元素数组。

在第二个示例中,您正在分配一个 0 元素std::string数组,但您需要一个 1 元素数组。

试试这个:

std::unique_ptr<std::string[]> strings(new std::string[1]); // <-- NOT 0!
// Or, if you are using C++14:
// auto strings = std::make_unique<string[]>(1);
strings[0] = "test";
testparam.AddString("filename", std::move(strings), 1);

或者:

testparam.AddString("filename", std::unique_ptr<std::string[]>(new std::string[1]{"test"}), 1);