Возврат уникального указателя void из функции


11

Чтобы получить функцию void *из CI, нужно сделать что-то вроде этого (очень простой пример):

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

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



1
Пожалуйста, объясните, какая у вас проблема с этим.
молбднило

1
Смотрите этот ответ для универсального void 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

Попробуйте вместо этого вернуть указатель на массив символов:

#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.