Zwracanie unikalnego wskaźnika pustki z funkcji

11

Dostać void * z funkcji w CI, zrobiłbym coś takiego (bardzo prosty przykład):

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

Jak osiągnąć ten sam rezultat podczas używania std::unique_ptr<>?

ZeppRock
źródło
1
Wyjaśnij, z czym masz problem.
molbdnilo
1
Zobacz tę odpowiedź dla ogólnej pustki unikatowy_ptr: stackoverflow.com/a/39288979/2527795
vll
Pamiętaj, że prawie nigdy nie powinno być powodu, aby używać mallocw C ++ w ten sposób. Zwracasz wskaźnik do surowej pamięci, w której musisz umieścić nowe obiekty, zanim będziesz mógł z nich korzystać. Jeśli nie masz dobrego powodu, aby utworzyć obiekty w późniejszym czasie niż przy przydzielaniu pamięci, powinieneś użyć newlub, std::make_uniquektóry przydzieli pamięć, a także utworzyć odpowiednie obiekty. W obu przypadkach std::vectorze reservejest prob. też lepiej. Nawet jeśli ich nie używasz, operator newto idiomatyczny sposób alokacji pamięci malloc.
orzech

Odpowiedzi:

18

Aby użyć, musisz określić niestandardowy usuwacz void jako unique_ptr„s typu argumentu tak:

#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());
}
Prawdziwie świeże
źródło
2

Uproszczenie odpowiedzi @ RealFresh przy użyciu std::freebezpośrednio jako separatora zamiast konstruowania funktora:

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

Zobacz jednak mój komentarz do pytania.

orzech włoski
źródło
1

Zastanów się nad zwróceniem wskaźnika do tablicy znaków:

#include <memory>

std::unique_ptr<char[]> get_ptr(std::size_t size)
{
    return std::make_unique<char[]>(size);
}
Toby Speight
źródło