【问题标题】:Giving char* to std::string for management (to eventually free memory)将 char* 提供给 std::string 进行管理(最终释放内存)
【发布时间】:2021-05-26 22:52:38
【问题描述】:

我必须使用一个库函数,它为生成的字符串分配一点内存并返回 char*,期望调用者最终使用 free() 释放内存。

// Example declaration of the library function:
char* foo();
// ...
// Example usage:
auto foo_str = foo();
// ...
free(foo_str);

是否可以从这个指针构造一个std::string,将内存的所有权传递给字符串对象,以便在字符串被破坏时释放它?我知道我可以实现自己的包装器来提供这种 RAII 行为,但我猜这个轮子已经被发明过一次了。

【问题讨论】:

  • 用你的原始指针创建一个std::unique_ptr 怎么样?还是 C++11 不是一个选项?
  • unique_ptr 不使用free()。它将使用某种形式的操作符删除。
  • @Peter unique_ptr 可以删除,但你想删除它。
  • @Michael 当然是unique_ptr!我没有考虑到这一点而失败了。当然 C++11 是一个选项,我用它标记了这个问题:)
  • 啊,问这个问题一个多月后是-1。我希望对所需的 cmets 投反对票。

标签: c++ c++11


【解决方案1】:

您可以从 char* 指针构造 std::string,但 std::string 将自行分配 char 数组。您仍然需要释放库返回的 char* :

char* c = foo();
std::string foo_str( c );
free( c );

您还可以创建一个确保删除 char* 并返回 std::string 的函数:

std::string char_to_string_with_free( const char* c )
{
    std::string str( c );
    free( c );
    return str;
}

【讨论】:

  • return std::move( str );// std::move if using C++11 std::move 可以防止返回值优化,从而导致代码效率降低。
  • @Michael 谢谢,我调整了答案
【解决方案2】:

不,您不能将string 用于此类事情。 string 始终拥有自己的缓冲区,并将分配和释放自己的缓冲区。您不能所有权转移到string。我什至不知道有没有这样的提议。

有一个容器,您可以将所有权转移到其中:unique_ptr:

struct free_deleter {
    void operator()(void* p) {
        free(p);
    }
};

std::unique_ptr<char, free_deleter> foo_str = foo();

【讨论】:

  • 我什至没有考虑unique_ptr,这是显而易见的解决方案。 +1 用于展示如何替换删除器。
  • 所以,如果我自己的 C++ 函数应该返回 std::string -- 带有 C 函数返回的内容(例如 asprintf),唯一的选项是通过构造新的string-object 来复制该内存,是吗?真是浪费……叹息……
【解决方案3】:

AFAIK std::string 没有这样的构造函数,它拥有char* 的所有权。无论如何,在分配它的库之外释放内存(如果我们谈论共享对象或 DLL)是一个坏主意。

【讨论】:

  • 库的文档明确指出必须释放指针。
  • 通常在这种情况下库会提供一个函数来释放其中分配的内存。
  • @ElohimMeth, asprintf 是一个很好的——如果被低估了——一个函数的例子,它不会......
猜你喜欢
  • 2011-08-06
  • 1970-01-01
  • 2012-03-03
  • 2011-06-26
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多