是否可以将std :: basic_string用作char *的包装器?

时间:2019-05-22 13:56:12

标签: c++ c++11 memory-management stl

我有第三方库,该库返回由strdup(分别为wcsdup函数)在其中创建的char *(和wchar_t *)。

我想避免在代码末尾手动调用free。

是否可以为std :: basic_string编写分配器,以便处理该库返回的C字符串?理想情况下,我根本不想分配任何新内存,而是使用返回的内存块(字符串应该是常量)。

4 个答案:

答案 0 :(得分:8)

可悲的是,std :: string进行自己的内存管理,并且无法重用已分配的字符串。

您可以将它们复制到std :: string并立即将其删除,但这将调用您试图避免的所有行为。

您可以做的就是立即使用自定义删除器声明一个unique_ptr。如果超出范围,它将调用删除器,即free()。同时,您可以像使用原始指针一样使用它。

std::unique_ptr<char, decltype(free)*> RAII(makeAPICall(), free);

将来,您可以为std :: string_view创建一个拥有的包装,在短期内滚动自己的包装可能会有好处,但是除非您拥有更新了所有功能的较新的stdlib(c ++ 17)采取string_view的方法我认为这是徒劳的。

答案 1 :(得分:4)

您不能使用_t()std::basic_string管理它自己的内存,因此它将分配新的存储并将数据复制到字符串中。您仍然必须手动从返回的指针释放存储。

如果可以使用C ++ 17,则可以使用std::basic_string,因为它将仅保存指针的副本,但是您遇到了同样的问题,您需要手动调用该函数的释放函数。指针完成后。

您可以做的是将std::basic_string_viewstd::unique_ptr与自定义删除器一起使用,以存储从函数返回的指针,这样它将自动为您重新分配内存。然后,如果您可以使用C ++ 17,则可以获取指向该指针的std::shared_ptr,以便无需复制就可以使用所有字符串函数。否则,可以使用std::basic_string_view中的c字符串函数来使用它或编写自己的<cstring>版本(或找到具有类似this one的C ++ 11库)

答案 2 :(得分:2)

  

我想避免在代码末尾手动调用free。

如果该库没有这样做,那么您将无法避免调用free(不管是否有意泄漏内存)。

如果库本身不使用字符串,那么如果您想使用std::stringstd::wstring,则可以使用接受CharT*的构造函数,并在创建后立即使用字符串,使用free释放原始字符串。

如果您希望避免其他分配和复制,那么std::string是不可行的。当指针超出范围时,可以使用智能指针进行释放。

答案 3 :(得分:2)

中有string_view

template<class T, class Deleter=std::default_delete<T>>
struct string_view_buff : std::string_view<T> {
  std::unique_ptr<T[]> buff;
  explicit string_view_buff( T* in, Deleter d = {} ):
    buff( in, std::move(d) ),
    std::string_view<T>(in) {}
};

类似的东西可以获取缓冲区的所有权,并同时公开类似字符串的功能,而无需额外的堆分配。 (代码未经测试)

在此之前,否,std::string分配和管理自己的内存。您不能为其提供缓冲区和删除功能。