Restituisce un puntatore vuoto univoco da una funzione


11

Per ottenere un void *da una funzione in CI farebbe qualcosa del genere (esempio molto semplice):

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

Come posso ottenere lo stesso risultato durante l'utilizzo std::unique_ptr<>?



1
Spiega quale problema stai riscontrando nel farlo.
molbdnilo,

1
Vedere questa risposta per generico unique_ptr vuoto: stackoverflow.com/a/39288979/2527795
VII

Si noti che non dovrebbe quasi mai esserci un motivo per utilizzare mallocin C ++ in questo modo. Stai restituendo un puntatore alla memoria non elaborata, in cui devi posizionare nuovi oggetti prima che ti sia permesso di usarlo. Se non si ha una buona ragione per creare gli oggetti in un secondo momento rispetto a quando si sta allocando la memoria, è necessario utilizzare newo std::make_uniqueche allocerà la memoria, nonché creare oggetti appropriati. In entrambi i casi std::vectorcon reserveis prob. anche meglio. Anche se non li usi, non operator newè il modo idiomatico di allocare memoria malloc.
noce

Risposte:


18

È necessario specificare il deleter personalizzato per poter utilizzare voidcome unique_ptrargomento del tipo in questo modo:

#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

Una semplificazione della risposta di @ RealFresh usando std::freedirettamente come deleter invece di costruire un funzione:

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

Vedi il mio commento sulla domanda, però.


1

Valuta invece di restituire un puntatore a char-array:

#include <memory>

std::unique_ptr<char[]> get_ptr(std::size_t size)
{
    return std::make_unique<char[]>(size);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.