使用 C++ shared_ptr 用删除器包装 C 结构
Use C++ shared_ptr to wrap C struct with deleter
这里是初学者的问题:假定在 C 中有一个 C 库具有以下假定用法:
struct c_struct* c_obj = NULL;
func(&c_obj); //mallocs and fills c_struct
free_c_struct(c_obj); //my reponsibility to free it
用 C++ 包装它的方法是什么 shared_ptr?
以这种方式尝试 - 删除器 (free_c_struct) 不起作用:
{
struct c_struct* c_obj = nullptr;
std::shared_ptr<struct c_struct> ptr (c_obj, free_c_struct);
//
// some amount of code
//
func(&c_obj);
//
// yet some amount of code, could return, or throw
// so I'm supposing "smart" functionality would do the work to free memory
//
//
//block ends, expect deleter to be called here
}
在块末 nullptr 被传递给 free_c_struct,但我想传递 malloc 的地址。我是不是完全漏掉了什么?
感谢您的关注。
更新:
一些有问题的方式:
void deleter(struct c_struct** o) {
free_c_struct(*o);
}
{
struct c_struct* c_obj = nullptr;
std::shared_ptr<struct c_struct*> c_obj_ptr (&c_obj, deleter);
//
// some amount of code
//
func(&c_obj);
}
这似乎符合我的要求,但看起来很奇怪,我应该编写自己的删除程序(我宁愿不这样做)。
std::shared_ptr<struct c_struct> ptr (c_obj, free_c_struct);
创建一个指向对象 c_obj
指向的共享指针。由于此时 c_obj
始终具有值 nullptr
,因此 ptr
也将始终使用 nullptr
进行初始化。对 c_obj
的进一步更改对 ptr
没有影响,地址已被复制。
解决方案是先用您的函数初始化 c_obj
,然后 然后 使用它来初始化您的共享指针。只需在初始化 ptr
.
之前放置 func(&c_obj);
由 shared_ptr
管理的指针与原始指针不同 - 它是它的副本。结果,您创建了一个管理空指针的 std::shared_ptr
对象。
当您稍后在 同一指针的另一个副本 上调用 func
时,您更改了原始指针的值,但由 std::shared_ptr
管理的指针保持不变,保持为空。
由于无法更改 shared_ptr
管理的指针的值,解决此问题的唯一方法是在将指针传递给 std::shared_ptr
进行管理之前初始化指针。
这里是初学者的问题:假定在 C 中有一个 C 库具有以下假定用法:
struct c_struct* c_obj = NULL;
func(&c_obj); //mallocs and fills c_struct
free_c_struct(c_obj); //my reponsibility to free it
用 C++ 包装它的方法是什么 shared_ptr? 以这种方式尝试 - 删除器 (free_c_struct) 不起作用:
{
struct c_struct* c_obj = nullptr;
std::shared_ptr<struct c_struct> ptr (c_obj, free_c_struct);
//
// some amount of code
//
func(&c_obj);
//
// yet some amount of code, could return, or throw
// so I'm supposing "smart" functionality would do the work to free memory
//
//
//block ends, expect deleter to be called here
}
在块末 nullptr 被传递给 free_c_struct,但我想传递 malloc 的地址。我是不是完全漏掉了什么?
感谢您的关注。
更新:
一些有问题的方式:
void deleter(struct c_struct** o) {
free_c_struct(*o);
}
{
struct c_struct* c_obj = nullptr;
std::shared_ptr<struct c_struct*> c_obj_ptr (&c_obj, deleter);
//
// some amount of code
//
func(&c_obj);
}
这似乎符合我的要求,但看起来很奇怪,我应该编写自己的删除程序(我宁愿不这样做)。
std::shared_ptr<struct c_struct> ptr (c_obj, free_c_struct);
创建一个指向对象 c_obj
指向的共享指针。由于此时 c_obj
始终具有值 nullptr
,因此 ptr
也将始终使用 nullptr
进行初始化。对 c_obj
的进一步更改对 ptr
没有影响,地址已被复制。
解决方案是先用您的函数初始化 c_obj
,然后 然后 使用它来初始化您的共享指针。只需在初始化 ptr
.
func(&c_obj);
由 shared_ptr
管理的指针与原始指针不同 - 它是它的副本。结果,您创建了一个管理空指针的 std::shared_ptr
对象。
当您稍后在 同一指针的另一个副本 上调用 func
时,您更改了原始指针的值,但由 std::shared_ptr
管理的指针保持不变,保持为空。
由于无法更改 shared_ptr
管理的指针的值,解决此问题的唯一方法是在将指针传递给 std::shared_ptr
进行管理之前初始化指针。