Namensräume
Varianten
Aktionen

realloc

Von cppreference.com
< c‎ | memory
Definiert im Header <stdlib.h>
void *realloc( void *ptr, size_t new_size );

Weist den gegebenen Speicherbereich neu zu. Wenn ptr nicht NULL ist, muss er zuvor von malloc, calloc oder realloc zugewiesen und noch nicht mit einem Aufruf von free oder realloc freigegeben worden sein. Andernfalls sind die Ergebnisse undefiniert.

Die Neuzuweisung erfolgt entweder durch

a) Erweitern oder Verkleinern des bestehenden Bereichs, auf den ptr zeigt, falls möglich. Der Inhalt des Bereichs bleibt bis zur 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 der kleineren der neuen und alten Größen entspricht, 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 NULL ist, entspricht das Verhalten dem Aufruf von malloc(new_size).

Andernfalls

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 ein nicht-null Zeiger, der nicht zum Zugriff auf Speicher verwendet werden kann). Eine solche Verwendung ist veraltet (gemäß C DR 400).(seit C17)

(bis C23)

wenn new_size null ist, ist das Verhalten undefiniert.

(seit C23)

realloc ist threadsicher: Es verhält sich so, als würde es nur auf die Speicherorte zugreifen, die über sein Argument sichtbar sind, und nicht auf beliebigen statischen Speicher.

Ein vorheriger Aufruf von free oder realloc, der eine Speicherregion freigibt, *synchronisiert* mit einem Aufruf jeder Speicherzuordnungsfunktion, einschließlich realloc, die dieselbe oder einen Teil derselben Speicherregion zuordnet. Diese Synchronisation erfolgt nach jedem Zugriff auf den Speicher durch die freigebende Funktion und vor jedem Zugriff auf den Speicher durch realloc. Es gibt eine einzige Gesamtordnung aller Speicherzuordnungs- und Freigabefunktionen, die auf einer bestimmten Speicherregion operieren.

(seit C11)

Inhalt

[bearbeiten] Parameter

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

[bearbeiten] Rückgabewert

Bei Erfolg wird ein Zeiger auf den Anfang des neu zugewiesenen Speichers zurückgegeben. Um Speicherlecks zu vermeiden, muss der zurückgegebene Zeiger mit free oder realloc freigegeben werden. Der ursprüngliche Zeiger ptr wird ungültig und jeder Zugriff darauf führt zu undefiniertem Verhalten (auch wenn die Neuzuweisung vor Ort erfolgte).

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

[bearbeiten] Hinweise

Ursprünglich (in C89) wurde die Unterstützung für null Größe hinzugefügt, um Code wie z.B. zu ermöglichen

OBJ *p = calloc(0, sizeof(OBJ)); // "zero-length" placeholder
/*...*/
while (1)
{
    p = realloc(p, c * sizeof(OBJ)); // reallocations until size settles
    /* code that may change c or break out of loop */
}

[bearbeiten] Beispiel

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void print_storage_info(const int* next, const int* prev, int ints)
{
    if (next)
        printf("%s location: %p. Size: %d ints (%ld bytes).\n",
               (next != prev ? "New" : "Old"), (void*)next, ints, ints * sizeof(int));
    else
        printf("Allocation failed.\n");
}
 
int main(void)
{
    const int pattern[] = {1, 2, 3, 4, 5, 6, 7, 8};
    const int pattern_size = sizeof pattern / sizeof(int);
    int *next = NULL, *prev = NULL;
 
    if ((next = (int*)malloc(pattern_size * sizeof *next))) // allocates an array
    {
        memcpy(next, pattern, sizeof pattern); // fills the array
        print_storage_info(next, prev, pattern_size);
    }
    else
        return EXIT_FAILURE;
 
    // Reallocate in cycle using the following values as a new storage size.
    const int realloc_size[] = {10, 12, 512, 32768, 65536, 32768};
 
    for (int i = 0; i != sizeof realloc_size / sizeof(int); ++i)
    {
        if ((next = (int*)realloc(prev = next, realloc_size[i] * sizeof(int))))
        {
            print_storage_info(next, prev, realloc_size[i]);
            assert(!memcmp(next, pattern, sizeof pattern));  // is pattern held
        }
        else // if realloc failed, the original pointer needs to be freed
        {
            free(prev);
            return EXIT_FAILURE;
        }
    }
 
    free(next); // finally, frees the storage
    return EXIT_SUCCESS;
}

Mögliche Ausgabe

New location: 0x144c010. Size: 8 ints (32 bytes).
Old location: 0x144c010. Size: 10 ints (40 bytes).
New location: 0x144c450. Size: 12 ints (48 bytes).
Old location: 0x144c450. Size: 512 ints (2048 bytes).
Old location: 0x144c450. Size: 32768 ints (131072 bytes).
New location: 0x7f490c5bd010. Size: 65536 ints (262144 bytes).
Old location: 0x7f490c5bd010. Size: 32768 ints (131072 bytes).

[bearbeiten] Referenzen

  • C23-Standard (ISO/IEC 9899:2024)
  • 7.22.3.5 Die Funktion realloc (p: TBD)
  • C17-Standard (ISO/IEC 9899:2018)
  • 7.22.3.5 Die Funktion realloc (p: 254)
  • C11-Standard (ISO/IEC 9899:2011)
  • 7.22.3.5 Die Funktion realloc (p: 349)
  • C99-Standard (ISO/IEC 9899:1999)
  • 7.20.3.4 Die Funktion realloc (p: 314)
  • C89/C90-Standard (ISO/IEC 9899:1990)
  • 4.10.3.4 Die Funktion realloc

[bearbeiten] Siehe auch

C++ Dokumentation für realloc