Конвертировать unique_ptr в void * и обратно, мне нужно бесплатно? - PullRequest
3 голосов
/ 08 ноября 2019

В моем коде я использую библиотеку с функцией store_pointer, которая принимает void* и сохраняет ее в памяти. Затем есть другая функция retrieve_pointer(), которая возвращает мне void *, у меня нет контроля над этой библиотекой, поэтому я не могу изменить поведение функции.

Теперь мне нужно передать переменнуюк этой функции и вернуть указатель, у меня есть код, настроенный следующим образом:

struct Task
{
    int mId;
    Task(int id ) :mId(id)
    {
        std::cout<<"Task::Constructor"<<std::endl;
    }
    ~Task()
    {
        std::cout<<"Task::Destructor"<<std::endl;
    }
};

std::unique_ptr<Task> taskPtr(new Task(23));
store_pointer(&taskPtr);

// do stuff that doesn't involve taskPtr

Task *new_taskPtr = reinterpret_cast<Task *>(retrieve_pointer());

// do stuff with new_taskPtr pointer

Сейчас все это работает, но мне интересно, нужно ли удалять указатель *new_taskPtr или reinterpret_cast «восстанавливает» указатель на unique_ptr, поэтому память будет автоматически удаляться при выходе из области видимости / завершении программы.

Ответы [ 2 ]

3 голосов
/ 08 ноября 2019
std::unique_ptr<Task> taskPtr(new Task(23));

Когда эта переменная выходит за пределы области, динамическое распределение будет удалено. В этом нет необходимости, и вы не должны удалять его самостоятельно, если только вы не вызовете release для уникального указателя, который является единственным способом передачи владения из уникального указателя (помимо передачи владения другому уникальному указателю).

Любое приведение, которое вы можете сделать, не влияет на это.

1 голос
/ 08 ноября 2019

Вы храните ссылку на unique_ptr:

store_pointer(&taskPtr);

Пока вы не перемещаете taskPtr или не связываетесь с его внутренним указателем, вы в безопасности и не нуждаетесь в delete,

Обратите внимание, что если taskPtr выходит за рамки ранее, чем пользователь, у вас будет свисающая ссылка.

...