Devolver un puntero vacío único desde una función

11

Para obtener un void *de una función en CI haría algo como esto (ejemplo muy básico):

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

¿Cómo logro el mismo resultado cuando lo uso std::unique_ptr<>?

ZeppRock
fuente
1
Por favor, explique qué problema tiene al hacerlo.
molbdnilo
1
Vea esta respuesta para void genérico unique_ptr: stackoverflow.com/a/39288979/2527795
vll
Tenga en cuenta que casi nunca debería haber una razón para usar mallocen C ++ como este. Está devolviendo un puntero a la memoria sin procesar, en la que necesita colocar objetos nuevos antes de poder usarlo. Si no tiene una buena razón para crear los objetos más tarde que cuando está asignando memoria, entonces debe usar newo std::make_uniqueque asignará memoria, así como crear objetos apropiados. En cualquier caso std::vectorcon reservees prob. mejor también Incluso si no usa estos, operator newes la forma idiomática de asignar memoria, no malloc.
nogal

Respuestas:

18

Debe especificar un eliminador personalizado para usarlo voidcomo unique_ptrargumento de tipo de esta manera:

#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());
}
Muy fresco
fuente
2

Una simplificación de la respuesta de @ RealFresh usando std::freedirectamente como eliminador en lugar de construir un functor:

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

Sin embargo, vea mi comentario sobre la pregunta.

nuez
fuente
1

Considere devolver un puntero a char-array en su lugar:

#include <memory>

std::unique_ptr<char[]> get_ptr(std::size_t size)
{
    return std::make_unique<char[]>(size);
}
Toby Speight
fuente