使用 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 进行管理之前初始化指针。