Rückgabe eines eindeutigen Void-Zeigers von einer Funktion

11

Um void *eine Funktion von einer Funktion in CI zu erhalten, gehen Sie wie folgt vor (sehr einfaches Beispiel):

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

Wie erreiche ich das gleiche Ergebnis bei der Verwendung std::unique_ptr<>?

ZeppRock
quelle
1
Bitte erläutern Sie, welches Problem Sie damit haben.
Molbdnilo
1
Siehe diese Antwort für generische Leere unique_ptr: stackoverflow.com/a/39288979/2527795
vll
Bitte beachten Sie, dass es fast nie einen Grund geben sollte, mallocC ++ wie dieses zu verwenden. Sie geben einen Zeiger auf den Rohspeicher zurück, in den Sie neue Objekte einfügen müssen, bevor Sie ihn verwenden dürfen. Wenn Sie keinen guten Grund haben, die Objekte zu einem späteren Zeitpunkt als beim Zuweisen von Speicher zu erstellen, sollten Sie verwenden newoder verwenden std::make_unique, um Speicher zuzuweisen, und geeignete Objekte erstellen. In beiden Fällen ist std::vectormit reserveprob. besser auch. Auch wenn Sie diese nicht verwenden, operator newist dies die idiomatische Art, Speicher zuzuweisen, nicht malloc.
Walnuss

Antworten:

18

Sie müssen einen benutzerdefinierten Löscher angeben, um Folgendes voidals Typargument verwenden zu können unique_ptr:

#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());
}
Echt frisch
quelle
2

Eine Vereinfachung der Antwort von @ RealFresh, die std::freedirekt als Deleter verwendet wird, anstatt einen Funktor zu erstellen :

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

Siehe jedoch meinen Kommentar zu der Frage.

Nussbaum
quelle
1

Ziehen Sie stattdessen einen Zeiger auf char-array zurück:

#include <memory>

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