我需要将API用作项目的一部分,该项目包括名为ParamSet
的类,该类的方法定义如下:
void AddString(const std::string &, std::unique_ptr<std::string[]> v, int nValues);
该方法的目的是向对象添加字符串数组以描述某些参数。例如,一个ParamSet
对象可能需要一个“文件名”参数,该参数指向一个nValues
字符串数组。
但是,当我尝试将unique_ptr
方法传递给仅包含1个字符串的数组时,除非我定义了{{1},否则代码段会在调用ParamSet
对象的析构函数时出错。 }。
以下代码在调用unique_ptr
或Clear()
时导致段故障。
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的调用之外创建它却不会。
答案 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);