【发布时间】:2017-09-27 16:48:03
【问题描述】:
我在围绕我正在使用的 C API 的 C++ 标头包装器中找到了这段代码:
static string GetString(const char* chString)
{
string strValue;
if (NULL != chString)
{
strValue.swap(string (chString));
releaseMemory((void*&)chString);
chString = NULL;
}
return strValue;
}
我想作者试图给字符串strValuechString 的所有权,然后释放空缓冲区。我怀疑这是非常错误的(包括它是 const char*),但它实际上似乎适用于 MSVC 12。至少我还没有看到它崩溃。
假设 C API 和 C++ 库使用相同的堆(以便字符串可以在必要时重新分配缓冲区并最终释放它),有没有办法正确实现这一点?这个怎么样?
template <typename T> struct Deleter { void operator()(T o) { releaseMemory((void*&)o); } };
static std::string GetString(char* chString)
{
if (NULL == chString)
return std::string();
return std::string(std::unique_ptr<char[], Deleter<char[]>>(chString).get());
}
再次假设 C API 使用与 std::string 相同的堆。
如果这也是非常错误的,那么是否有一个不可变的、拥有 C 风格的字符串包装器?类似于string_view 但不可变(所以const char* 输入可以)和拥有(所以它删除了C 字符串,可能在其dtor 中使用自定义删除器)?
【问题讨论】:
-
C API 应该记录那个字符串是什么,如果它以某种方式被
malloc-ed 负责free-ing 它。 -
std::string不拥有chString指向的缓冲区的所有权。它会复制它。 -
strValue.swap(string (chString));是strValue = chString;的不必要的复杂化。 -
unique_ptr方法是错误的,因为它在应该使用releaseMemory时使用了delete []。也没有所有权。GetString创建了const char *的副本,然后以一种奇怪的方式破坏了原始文件。chString = NULL;也完全没有意义。 -
@MattChambers 是的。就像 molbdnilo 所说,如果你直接将
chString分配给strValue,你会得到基本相同的结果。
标签: c++ optimization memory-management