自定义删除器以通过 std::unique_ptr 释放二维数组
Customize the deleter to deallocate a 2D array through std::unique_ptr
假设我正在将环境变量列表从给定 map<string, string>
解析到 unique_ptr<char*[]>
持有的 2D 内存。但是,我不确定如何为这个 2D 内存盒自定义删除器?
// Given: env (type of map<string, string>)
// Return: unique_ptr<char*[]> (with customized deleter)
// Prepare for parsing the environment to c-style strings
auto idx = size_t{0};
// What should I fill for `ret` a proper deleter that won't give memory leak?
auto ret = std::make_unique<char*[]>(env.size() + 1, ???);
for(const auto& kvp : env) {
auto entry = kvp.first + "=" + kvp.second;
ret[idx] = new char[entry.size() + 1];
strncpy(ret[idx], entry.c_str(), entry.size() + 1);
++idx;
}
ret[idx] = nullptr; // For the later use of exec call
return ret;
显然,上面的代码泄漏了,因为内部 for 循环中的 new operator
。
std::make_unique
没有接受删除器作为参数的版本(顺便说一下,std::make_unique
是 C++14,而不是 C++11)。试试这个:
size_t size = env.size() + 1;
auto ret = std::unique_ptr<char*, std::function<void(char**)> >(
new char* [size],
[size](char** ptr)
{
for(size_t i(0); i < size; ++i)
{
delete[] ptr[i];
}
delete[] ptr;
}
);
您可以将 ret.get()
传递给 execvpe。
假设我正在将环境变量列表从给定 map<string, string>
解析到 unique_ptr<char*[]>
持有的 2D 内存。但是,我不确定如何为这个 2D 内存盒自定义删除器?
// Given: env (type of map<string, string>)
// Return: unique_ptr<char*[]> (with customized deleter)
// Prepare for parsing the environment to c-style strings
auto idx = size_t{0};
// What should I fill for `ret` a proper deleter that won't give memory leak?
auto ret = std::make_unique<char*[]>(env.size() + 1, ???);
for(const auto& kvp : env) {
auto entry = kvp.first + "=" + kvp.second;
ret[idx] = new char[entry.size() + 1];
strncpy(ret[idx], entry.c_str(), entry.size() + 1);
++idx;
}
ret[idx] = nullptr; // For the later use of exec call
return ret;
显然,上面的代码泄漏了,因为内部 for 循环中的 new operator
。
std::make_unique
没有接受删除器作为参数的版本(顺便说一下,std::make_unique
是 C++14,而不是 C++11)。试试这个:
size_t size = env.size() + 1;
auto ret = std::unique_ptr<char*, std::function<void(char**)> >(
new char* [size],
[size](char** ptr)
{
for(size_t i(0); i < size; ++i)
{
delete[] ptr[i];
}
delete[] ptr;
}
);
您可以将 ret.get()
传递给 execvpe。