提问人:D.J. Elkind 提问时间:6/12/2023 最后编辑:Jan SchultkeD.J. Elkind 更新时间:6/12/2023 访问量:260
std::unique_ptr 带有自定义删除器,用于包装 malloc 指针
std::unique_ptr with custom deleter for wrapping a malloc pointer
问:
我有一个 C 库函数:
uint8_t* c_func();
这要么返回分配了 的有效指针,要么返回错误。我想把它包装成如下:uint8_t
malloc()
NULL
std::unique_ptr()
struct FreeDeleter {
void operator()(void *p) const {
std::free(p);
}
};
template <typename T>
using unique_fptr = std::unique_ptr<T, FreeDeleter>;
std::free()
如果传递给它的指针是 ,则不执行任何操作,因此这应该按预期工作。NULL
这种设计是否正确,它是否遵循在 C++ 中包装原始指针的最佳实践?
答:
4赞
Sebastian Redl
6/12/2023
#1
是的,这是最佳做法。
我会更进一步,将 C 函数包装在一个函数中,该函数会立即将结果包装在unique_ptr中,这样您就不会忘记这样做。
但是,需要注意的是!如果 C 函数位于 Windows 上的共享库中,则它可能使用不同的堆,因此在主程序中使用 free 将无效。但是,除非库提供自己的自定义免费函数,否则您对此无能为力,在这种情况下,您无论如何都应该使用它。
评论
1赞
Eljay
6/12/2023
警告是正确的!我希望我能给超过+1。
0赞
D.J. Elkind
6/13/2023
由于我通常不在 Windows 上编程,所以我不知道这一点。只是出于好奇,这是否意味着在 Windows 上我的程序不能由共享库函数编辑内存?free()
malloc()
0赞
Sebastian Redl
6/13/2023
是的,这是一个潜在的问题。这取决于确切的设置。从理论上讲,如果 EXE 和 DLL 都动态链接到相同版本的 CRT DLL,则可以跨模块边界进行 malloc/free。但是,如果静态链接或链接到其他版本,则代码会中断。因为我们谈论的是 DLL,这意味着当替换 DLL 时,它甚至可能在不重新编译 EXE 的情况下中断!因此,最好不要冒险并采取相关的预防措施。
评论
std::unique_ptr
std::out_ptr_t
std::inout_ptr_t
void c_func(foo** ret)
std::unique_ptr
std::unique_ptr
std::is_trivially_destructible
类型,但这只是一个噱头FILE*
fclose
FILE*
iostream
fileno
或fdopen
以使用 POSIX 例程的能力。我还认为更易于阅读并且可能更快(更少的互斥锁/解锁周期)fprintf