Wie funktioniert `realloc` eigentlich im Hintergrund?

Lesezeit: 2 Minuten

Benutzer-Avatar
Ravindra Gupta

Wie realloc eigentlich im Hintergrund arbeiten? Wenn an alter Stelle nicht genug Speicher vorhanden ist, wird dieser zugeteilt zwei/viele Speicherblöcke und ein darauf zeigender Zeiger und der andere sind intern miteinander verknüpft oder wird die alte Region an einen neuen Ort kopiert, an dem genügend Speicher verfügbar ist, und der Zeiger auf die neue Adresse aktualisiert und den alten Speicher gelöscht?

Und ist das realloc ist Compiler/OS abhängig oder unabhängig?

Benutzer-Avatar
Sergej L.

realloc versucht, Ihren verfügbaren Speicherbereich zu erweitern, wenn genügend Speicher dahinter auf dem Heap verfügbar ist. Wenn nicht, dann ist es gleichbedeutend mit malloc ein Block der neuen Größe, memcpy Ihre Inhalte dort, free der alte Block. Dies ist sowohl vom Betriebssystem als auch vom Compiler unabhängig und hängt von der Implementierung ab libc gegen die Sie verlinken.

In ähnlicher Weise: mremap/MREMAP_MAYMOVE (verfügbar unter modernem Linux) versucht, Ihr virtuelles Mapping um die angeforderte Größe zu erweitern. Wenn dies nicht möglich ist, wird Ihre Zuordnung auf eine neue virtuelle Adresse verschoben, die über ausreichend VM-Speicherplatz verfügt, und Ihre Zuordnung wird dann erweitert. Dies geht sehr schnell, wenn Sie häufig große Mappings skalieren, da kein physisches Kopieren erfolgt.

  • Tatsächlich kann realloc auch den Speicherbereich reduzieren, wenn die size Argument ist niedriger als beim vorherigen Aufruf.

    – Calandoa

    9. Januar 2019 um 17:03 Uhr

Eine Implementierung von realloc() kann etwa so aussehen:

void * realloc(void *ptr, size_t size)
{
    // realloc() on a NULL pointer is the same as malloc().
    if (ptr == NULL)
        return malloc(size);

    size_t oldsize = malloc_getsize(ptr);

    // Are we shrinking an allocation? That's easy.
    if (size < oldsize) {
        malloc_setsize(ptr, size);
        return ptr;
    }

    // Can we grow this allocation in place?
    if (malloc_can_grow(ptr, size)) {
        malloc_setsize(ptr, size);
        return ptr;
    }

    // Create a new allocation, move the data there, and free the old one.
    void *newptr = malloc(size);
    if (newptr == NULL)
        return NULL;
    memcpy(newptr, ptr, oldsize);
    free(ptr);
    return newptr;
}

Beachten Sie, dass ich mehrere Funktionen aufrufe, deren Namen mit beginnen malloc_ hier. Diese Funktionen existieren (nach meinem besten Wissen) in keiner Implementierung; Sie sind als Platzhalter gedacht, aber die Zuweisung führt diese Aufgaben tatsächlich intern aus.

Seit der Umsetzung von realloc() von diesen internen Tools abhängt, ist seine Implementierung betriebssystemabhängig. Allerdings ist die realloc() Schnittstelle ist universell.

Wenn die Größe des alten Zeigers nicht geändert werden kann, wird ein neuer zugewiesen, der Inhalt kopiert und der alte freigegeben.

1368660cookie-checkWie funktioniert `realloc` eigentlich im Hintergrund?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy