1 元素分配数组的正确 unique_ptr 声明
Proper unique_ptr declaration of 1 element allocated array
我需要使用一个 API 作为项目的一部分,该项目包括一个名为 ParamSet
的 class,其方法定义如下:
void AddString(const std::string &, std::unique_ptr<std::string[]> v, int nValues);
该方法的目的是向对象添加一个字符串数组来描述一些参数。例如,一个 ParamSet
对象可能需要一个指向 nValues
字符串数组的 "filename" 参数。
但是,当我尝试将方法 a unique_ptr
传递给仅包含 1 个字符串的数组时,除非我定义 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
我不明白为什么在调用 AddString
的行中创建 unique_ptr
会导致段错误,但在调用之外创建它却不会。
问题是您使用非数组 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[]
.
的单元素数组
在您的第二个示例中,您正在分配一个 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);
我需要使用一个 API 作为项目的一部分,该项目包括一个名为 ParamSet
的 class,其方法定义如下:
void AddString(const std::string &, std::unique_ptr<std::string[]> v, int nValues);
该方法的目的是向对象添加一个字符串数组来描述一些参数。例如,一个 ParamSet
对象可能需要一个指向 nValues
字符串数组的 "filename" 参数。
但是,当我尝试将方法 a unique_ptr
传递给仅包含 1 个字符串的数组时,除非我定义 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
我不明白为什么在调用 AddString
的行中创建 unique_ptr
会导致段错误,但在调用之外创建它却不会。
问题是您使用非数组 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[]
.
在您的第二个示例中,您正在分配一个 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);