std::unique_ptr 用于需要免费的 C 函数

新手上路,请多包涵

想想一个 C 函数,它返回的东西必须是 free d,例如 POSIX 的 strdup() 。我想在 C++11 中使用该函数并避免任何泄漏的机会,这是正确的方法吗?

 #include <memory>
#include <iostream>
#include <string.h>

int main() {
    char const* t { "Hi stackoverflow!" };
    std::unique_ptr<char, void(*)(void*)>
        t_copy { strdup(t), std::free };

    std::cout << t_copy.get() << " <- this is the copy!" <<std::endl;
}

假设它是有道理的,是否可以对非指针使用类似的模式?例如对于 POSIX 的函数 open 返回一个 int

原文由 Paolo.Bolzoni 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 474
1 个回答

你所拥有的东西极有可能在实践中起作用,但并不完全正确。您可以使其更有可能按以下方式工作:

 std::unique_ptr<char, decltype(std::free) *>
    t_copy { strdup(t), std::free };

原因是 std::free 的函数类型不保证是 void(void*) 。它保证在传递 void* 时是可调用的,在这种情况下返回 void ,但至少有两种函数类型符合该规范:一种具有 C 链接,以及一个带有 C++ 链接。大多数编译器都不会注意这一点,但为了正确起见,您应该避免对此做出假设。

然而,即便如此,这也不是完全正确的。正如@PeterSom 在评论中指出的那样,C++ 允许实现例如使 std::free 成为一个重载函数,在这种情况下,您和我对 std::free 的使用都是模棱两可的。这不是授予 std::free 的特定权限,它是授予几乎所有标准库函数的权限。为了避免这个问题,需要一个自定义函数或仿函数(如他的回答)。

假设它是有道理的,是否可以对非指针使用类似的模式?

不适用于 unique_ptr ,它确实特定于指针。但是您可以创建自己的类,类似于 unique_ptr ,但不对被包装的对象做出假设。

原文由 user743382 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题