Retornando um ponteiro nulo exclusivo de uma função


11

Para obter uma void *função de um CI, seria algo assim (exemplo muito básico):

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

Como obtenho o mesmo resultado ao usar std::unique_ptr<>?



11
Por favor, explique o problema que você está tendo ao fazê-lo.
molbdnilo 16/01

11
Veja esta resposta para o void genérico unique_ptr: stackoverflow.com/a/39288979/2527795
vll 16/01/17

Observe que quase nunca deve haver um motivo para usar mallocem C ++ como este. Você está retornando um ponteiro para a memória bruta, na qual precisa colocar novos objetos antes de poder usá-lo. Se você não tiver um bom motivo para criar os objetos mais tarde do que quando estiver alocando memória, deverá usar newou o std::make_uniqueque alocará memória e criar objetos apropriados. Em ambos os casos std::vectorcom reserveé prov. melhor também. Mesmo que você não os use, operator newé a maneira idiomática de alocar memória, não malloc.
noz

Respostas:


18

Você precisa especificar deleter personalizado para usar voidcomo unique_ptrargumento de tipo assim:

#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

Uma simplificação da resposta do @ RealFresh usando std::freediretamente como deleter em vez de construir um functor:

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

Veja meu comentário sobre a questão, no entanto.


1

Considere retornar um ponteiro para char-array:

#include <memory>

std::unique_ptr<char[]> get_ptr(std::size_t size)
{
    return std::make_unique<char[]>(size);
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.