Retour d'un pointeur vide unique à partir d'une fonction

11

Obtenir un à void *partir d'une fonction dans CI ferait quelque chose comme ça (exemple très basique):

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

Comment obtenir le même résultat lors de l'utilisation std::unique_ptr<>?

ZeppRock
la source
1
Veuillez expliquer quel problème vous rencontrez.
molbdnilo
1
Voir cette réponse pour générique void unique_ptr: stackoverflow.com/a/39288979/2527795
vll
Veuillez noter qu'il ne devrait presque jamais y avoir de raison d'utiliser mallocen C ++ comme ceci. Vous retournez un pointeur vers la mémoire brute, dans lequel vous devez placer de nouveaux objets avant de pouvoir l'utiliser. Si vous n'avez pas une bonne raison de créer les objets plus tard que lorsque vous allouez de la mémoire, vous devez utiliser newou std::make_uniquequi allouera de la mémoire, ainsi que créer des objets appropriés. Dans les deux cas, std::vectoravec reserveprob. mieux aussi. Même si vous ne les utilisez pas, operator newc'est la façon idiomatique d'allouer de la mémoire, non malloc.
noyer

Réponses:

18

Vous devez spécifier un suppresseur personnalisé afin de l'utiliser voidcomme unique_ptrargument de type comme celui-ci:

#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());
}
Vraiment frais
la source
2

Une simplification de la réponse de @ RealFresh en utilisant std::freedirectement comme deleter au lieu de construire un foncteur:

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

Voir mon commentaire sur la question, cependant.

noyer
la source
1

Envisagez de renvoyer un pointeur vers char-array à la place:

#include <memory>

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