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

时间:2018-09-26 22:51:43

标签: c++ unique-ptr

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

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

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

但是,当我尝试将unique_ptr方法传递给仅包含1个字符串的数组时,除非我定义了{{1},否则代码段会在调用ParamSet对象的析构函数时出错。 }。

以下代码在调用unique_ptrClear()时导致段故障。

return

但是以下情况不会导致段错误。

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

我不明白为什么在调用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 的行中创建unique_ptr会导致段错误,但在to的调用之外创建它却不会。

2 个答案:

答案 0 :(得分:1)

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

语法可以是:

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

答案 1 :(得分:0)

std::unique_ptr的数组特化要求将数组分配给new[],因为默认情况下它使用delete[]来释放数组。

在第一个示例中,您要为std::string分配一个new对象,而不是为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);