Namespaces
Variants

std:: realloc

From cppreference.net
< cpp ‎ | memory ‎ | c
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Definiert in Header <cstdlib>
void * realloc ( void * ptr, std:: size_t new_size ) ;

Weist den angegebenen Speicherbereich neu zu ( implizit Objekte erzeugend im Zielbereich). Er muss zuvor durch std::malloc , std::calloc oder std::realloc alloziert und noch nicht mit std::free freigegeben worden sein, andernfalls sind die Ergebnisse undefiniert.

Die Neuzuweisung erfolgt entweder durch:

a) Erweitern oder Verkleinern des bestehenden, von ptr referenzierten Bereichs, falls möglich. Der Inhalt des Bereichs bleibt bis zur kleineren der neuen und alten Größen unverändert. Wenn der Bereich erweitert wird, ist der Inhalt des neuen Teils des Arrays undefiniert.
b) Zuweisen eines neuen Speicherblocks der Größe new_size Bytes, Kopieren des Speicherbereichs mit einer Größe entsprechend dem kleineren Wert der neuen und alten Größen und Freigeben des alten Blocks.

Wenn nicht genügend Speicher vorhanden ist, wird der alte Speicherblock nicht freigegeben und ein null-Zeiger zurückgegeben.

Wenn ptr ein Nullzeiger ist, ist das Verhalten dasselbe wie beim Aufruf von std:: malloc ( new_size ) .

Wenn new_size null ist, ist das Verhalten implementierungsdefiniert: Es kann ein null-Zeiger zurückgegeben werden (wobei der alte Speicherblock freigegeben werden kann oder nicht) oder es kann ein nicht-null-Zeiger zurückgegeben werden, der möglicherweise nicht zum Zugriff auf Speicher verwendet werden darf. Eine solche Verwendung ist veraltet (durch C DR 400 ). (seit C++20)

Die folgenden Funktionen müssen thread-sicher sein:

Aufrufe dieser Funktionen, die eine bestimmte Speichereinheit allozieren oder deallozieren, erfolgen in einer einzigen Gesamtordnung, und jeder solche Deallokationsaufruf happens-before der nächsten Allokation (falls vorhanden) in dieser Ordnung.

(seit C++11)

Inhaltsverzeichnis

Parameter

ptr - Zeiger auf den neu zuzuweisenden Speicherbereich
new_size - neue Größe des Arrays

Rückgabewert

Bei Erfolg gibt die Funktion einen Zeiger auf den Anfang des neu zugewiesenen Speichers zurück. Um einen Speicherverlust zu vermeiden, muss der zurückgegebene Zeiger mit std::free oder std::realloc freigegeben werden. Der ursprüngliche Zeiger ptr wird ungültig und jeglicher Zugriff darauf ist undefined behavior (selbst wenn die Neuzuweisung in-place erfolgte).

Bei Fehler wird ein Nullzeiger zurückgegeben. Der ursprüngliche Zeiger ptr bleibt gültig und muss möglicherweise mit std::free freigegeben werden.

Hinweise

Da die Neuzuordnung byteweises Kopieren beinhalten kann (unabhängig davon, ob der Bereich erweitert oder verkleinert wird), ist es notwendig (aber nicht ausreichend), dass diese Objekte vom Typ TriviallyCopyable sind.

Einige nicht-standardisierte Bibliotheken definieren ein Typ-Merkmal "BitwiseMovable" oder "Relocatable", das einen Typ beschreibt, der nicht über folgende Eigenschaften verfügt:

  • externe Referenzen (z.B. Knoten einer Liste oder eines Baums, die auf ein anderes Element verweisen), und
  • interne Referenzen (z.B. Member-Zeiger, die möglicherweise die Adresse eines anderen Members enthalten).

Objekte dieses Typs können auch dann aufgerufen werden, nachdem ihr Speicher neu zugewiesen wurde, selbst wenn ihre Kopierkonstruktoren nicht trivial sind.

Beispiel

#include <cassert>
#include <cstdlib>
#include <new>
class MallocDynamicBuffer
{
    char* p;
public:
    explicit MallocDynamicBuffer(std::size_t initial = 0) : p(nullptr)
    {
        resize(initial);
    }
    ~MallocDynamicBuffer() { std::free(p); }
    void resize(std::size_t newSize)
    {
        if (newSize == 0) // diese Prüfung ist nicht zwingend erforderlich,
        {
            std::free(p); // aber Realloc mit Nullgröße ist in C veraltet
            p = nullptr;
        }
        else
        {
            if (void* mem = std::realloc(p, newSize))
                p = static_cast<char*>(mem);
            else
                throw std::bad_alloc();
        }
    }
    char& operator[](size_t n) { return p[n]; }
    char operator[](size_t n) const { return p[n]; }
};
int main()
{
    MallocDynamicBuffer buf1(1024);
    buf1[5] = 'f';
    buf1.resize(10); // verkleinern
    assert(buf1[5] == 'f');
    buf1.resize(1024); // vergrößern
    assert(buf1[5] == 'f');
}

Siehe auch

C-Dokumentation für realloc