使用C ++ shared_ptr用Deleter包装C结构

时间:2019-09-26 17:30:53

标签: c++ wrapper smart-pointers

这里是初学者的问题:假设在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);
}

这似乎可以满足我的要求,但是看起来很奇怪,我应该编写自己的删除器(我宁愿不这样做)。

2 个答案:

答案 0 :(得分:3)

std::shared_ptr<struct c_struct> ptr (c_obj, free_c_struct);创建指向对象c_obj指向的共享指针。由于此时c_obj始终具有值nullptr,因此ptr也将始终使用nullptr进行初始化。 c_obj的进一步更改对ptr没有影响,该地址已被复制。

解决方案是先使用函数初始化c_obj,然后然后使用它初始化共享指针。只需将func(&c_obj);放在初始化ptr之前。

答案 1 :(得分:3)

shared_ptr管理的指针与原始指针不同,它是它的副本。结果,您创建了一个std::shared_ptr对象,该对象管理空指针。

以后您在同一指针的另一副本上调用func时,将更改原始指针的值,但是由std::shared_ptr管理的指针保持不变,并且保持不变为空。

由于无法更改shared_ptr管理的指针的值,因此解决此问题的唯一方法是在将指针传递给std::shared_ptr进行管理之前初始化指针。