Namensräume
Varianten
Aktionen

std::realloc

Von cppreference.com
< cpp‎ | memory‎ | c
 
 
Speicherverwaltungsbibliothek
(nur Exposition*)
Algorithmen für uninitialisierten Speicher
(C++17)
(C++17)
(C++17)
Beschränkte uninitialisierte
Speicher-Algorithmen
C-Bibliothek
realloc

Allocatoren
Speicherressourcen
Unterstützung für Garbage Collection
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
Uninitialisierter Speicher
Explizites Lebenszeitmanagement
 
Definiert in Header <cstdlib>
void* realloc( void* ptr, std::size_t new_size );

Reallokiert den gegebenen Speicherbereich (implizites Erstellen von Objekten im Zielbereich). Er muss zuvor von std::malloc, std::calloc oder std::realloc zugewiesen und noch nicht mit std::free freigegeben worden sein, andernfalls sind die Ergebnisse undefiniert.

Die Reallokation erfolgt entweder durch

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

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

Wenn ptr ein Nullzeiger ist, verhält sich die Funktion wie ein Aufruf von std::malloc(new_size).

Wenn new_size Null ist, ist das Verhalten implementierungsabhängig: Es kann ein Nullzeiger zurückgegeben werden (in diesem Fall kann der alte Speicherblock freigegeben werden oder auch nicht) oder es kann ein nicht-null Zeiger zurückgegeben werden, der nicht zum Zugriff auf Speicher verwendet werden kann. Eine solche Verwendung ist veraltet (gemäß C DR 400).(seit C++20)

Die folgenden Funktionen sind Thread-sicher erforderlich

Aufrufe dieser Funktionen, die eine bestimmte Speichereinheit zuweisen oder freigeben, erfolgen in einer einzigen Gesamtordnung, und jeder solche Freigabeaufruf happens-before die nächste Zuweisung (falls vorhanden) in dieser Ordnung.

(seit C++11)

Inhalt

[bearbeiten] Parameter

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

[bearbeiten] Rückgabewert

Bei Erfolg wird ein Zeiger auf den Beginn des neu zugewiesenen Speichers zurückgegeben. Um Speicherlecks zu vermeiden, muss der zurückgegebene Zeiger mit std::free oder std::realloc freigegeben werden. Der ursprüngliche Zeiger ptr wird ungültig und jeder Zugriff darauf ist undefiniertes Verhalten (auch wenn die Reallokation In-Place erfolgte).

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

[bearbeiten] Hinweise

Da die Reallokation eine byteweise Kopie beinhalten kann (unabhängig davon, ob der Bereich erweitert oder verkleinert wird), ist es notwendig (aber nicht hinreichend), dass die Objekte vom Typ TriviallyCopyable sind.

Einige nicht-standardmäßige Bibliotheken definieren eine Typ-Eigenschaft "BitwiseMovable" oder "Relocatable", die einen Typ beschreibt, der keine

  • externen Referenzen (z. B. Knoten einer Liste oder eines Baumes, die Referenzen auf andere Elemente halten) und
  • internen Referenzen (z. B. ein Member-Zeiger, der die Adresse eines anderen Members halten könnte) besitzt.

Objekte eines solchen Typs können nach der Reallokation ihres Speichers zugegriffen werden, auch wenn ihre Konstruktoren für die Kopie nicht trivial sind.

[bearbeiten] 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) // this check is not strictly needed,
        {
            std::free(p); // but zero-size realloc is deprecated in C
            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); // shrink
    assert(buf1[5] == 'f');
    buf1.resize(1024); // grow
    assert(buf1[5] == 'f');
}

[bearbeiten] Siehe auch

C-Dokumentation für realloc