Повернення неповторного покажчика порожнечі від функції


11

Щоб отримати void *функцію з CI, зробимо щось подібне (дуже базовий приклад):

void *get_ptr(size_t size)
{
    void *ptr = malloc(size);
    return ptr;
}

Як досягти однакового результату при використанні std::unique_ptr<>?



1
Поясніть, будь ласка, яку проблему у вас виникає.
molbdnilo

1
Дивіться цей відповідь для загального незначною unique_ptr: stackoverflow.com/a/39288979/2527795
Vll

Зверніть увагу, що майже ніколи не повинно бути причин використовувати mallocподібний C ++. Ви повертаєте вказівник на необроблену пам'ять, на яку вам потрібно розмістити нові об'єкти, перш ніж ви зможете ним користуватися. Якщо у вас немає вагомих причин створювати об'єкти пізніше, ніж тоді, коли ви виділяєте пам’ять, тоді вам слід використовувати newабо std::make_uniqueякий буде виділяти пам'ять, а також створювати відповідні об’єкти. В будь-якому випадку std::vectorз reserveє проблемою. краще теж. Навіть якщо ви їх не використовуєте, operator newце ідіоматичний спосіб розподілу пам'яті, чи не malloc.
волоський горіх

Відповіді:


18

Вам потрібно вказати спеціальний делетер, щоб використовувати voidяк unique_ptrаргумент типу типу:

#include <memory>
#include <cstdlib>

struct deleter {
    void operator()(void *data) const noexcept {
        std::free(data);
    }
};

std::unique_ptr<void, deleter> get_ptr(std::size_t size) {
    return std::unique_ptr<void, deleter>(std::malloc(size));
}

#include <cstdio>
int main() {
    const auto p = get_ptr(1024);
    std::printf("%p\n", p.get());
}

2

Спрощення відповіді @ RealFresh з використанням std::freeбезпосередньо в якості делетера замість побудови функтора:

auto get_ptr(std::size_t size) {
    return std::unique_ptr<void, decltype(&std::free)>(std::malloc(size), std::free);
}

Дивіться, проте, мій коментар до питання.


1

Спробуйте повернути покажчик на char-масив замість цього:

#include <memory>

std::unique_ptr<char[]> get_ptr(std::size_t size)
{
    return std::make_unique<char[]>(size);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.