std::realloc
| 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
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
|