我需要使用一个API作为项目的一部分,该项目包含一个名为ParamSet
的类,其方法定义如下:
void AddString(const std::string &, std::unique_ptr<std::string[]> v, int nValues);
该方法的目的是将字符串数组添加到对象以描述某些参数。例如,ParamSet
对象可能需要一个指向nValues
字符串数组的"filename“参数。
但是,当我尝试将unique_ptr
传递给只包含1个字符串的数组时,除非我以特定的方式定义unique_ptr
,否则在调用ParamSet
对象的析构函数时,代码会出错。
以下代码在调用Clear()
或return
时导致seg-fault。
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错误,而在调用的外部创建它却不会。
发布于 2018-09-27 07:10:58
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);
发布于 2018-09-27 07:03:40
问题是,您使用非数组new
来分配由unique_ptr<T[]>
管理的内存,然后该内存将继续使用数组delete[]
,从而导致未定义的行为。
语法可以是:
badparam.AddString("filename", std::unique_ptr<std::string[]>(new std::string[1]{"test"}), 1);
https://stackoverflow.com/questions/52527051
复制相似问题