自定义deleter以通过std::unique_ptr解除分配2D阵列

Customize the deleter to deallocate a 2D array through std::unique_ptr

本文关键字:ptr 解除分配 2D 阵列 unique 自定义 std deleter      更新时间:2023-10-16

假设我正在将环境变量列表从给定的map<string, string>解析到由unique_ptr<char*[]>持有的2D内存。然而,我不确定如何为这个2D内存盒定制deleter?

// 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接受deleter作为参数(顺便说一句,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。