Используйте C ++ shared_ptr, чтобы обернуть структуру C с помощью средства удаления - PullRequest
0 голосов
/ 26 сентября 2019

Вопрос новичка здесь: учитывая, что в 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?Попробовал это так - delete (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'ed адрес.Я что-то упускаю полностью?

Спасибо за ваше внимание.

ОБНОВЛЕНИЕ:

Какой-то сомнительный способ:

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 ]

3 голосов
/ 26 сентября 2019

Указатель, которым управляет shared_ptr, отличается от оригинала - это его копия.В результате вы создаете объект std::shared_ptr, который управляет нулевым указателем.

При последующем вызове func на другой копии того же указателя вы изменяете значение оригиналауказатель, но управляемый std::shared_ptr остается неизменным и остается нулевым.

Поскольку нет способа изменить значение указателя, управляемого shared_ptr, единственный способ решить эту проблему - этоинициализировать указатель перед передачей его std::shared_ptr для управления.

3 голосов
/ 26 сентября 2019

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.

...