Verlieren wir Daten in einem Puffer nach der Neuzuweisung?

Lesezeit: 3 Minuten

Ich habe Probleme zu verstehen, wie realloc funktioniert. Wenn ich einen Puffer mallociert und Daten in diesen Puffer kopiert habe, sagen wir “AB”:

 +------------+
 | A | B | \0 |
 +------------+

dann habe ich den Puffer neu zugewiesen, gehen Daten verloren (sogar ein einzelnes Byte)?; oder erweitert es nur den Puffer? :

 +------------------------+
 | A | B | \0 | ? | ? | ? |
 +------------------------+

Code:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(void){

    char* buffer    = (char*) malloc( sizeof(char) * 3 );
    strncpy(buffer, "AB", 2);

    buffer          = (char*) realloc(buffer, sizeof(char) * 6); /* Will there be any lost here? */
    free(buffer);
    return(0);
}

Benutzeravatar von David Heffernan
David Heffernan

EIN realloc der die Größe des Blocks erhöht, behält den Inhalt des ursprünglichen Speicherblocks. Auch wenn die Größe des Speicherblocks nicht geändert werden kann, werden die alten Daten in den neuen Block kopiert. Für ein realloc Dadurch wird der Block verkleinert, die alten Daten werden abgeschnitten.

Beachten Sie, dass Ihr Anruf an realloc bedeutet, dass Sie Ihre Daten verlieren, wenn aus irgendeinem Grund die realloc scheitert. Das ist weil realloc schlägt durch Rückkehr fehl NULLaber in diesem Fall ist der ursprüngliche Speicherblock immer noch gültig, aber Sie können nicht mehr darauf zugreifen, da Sie den Zeiger überschrieben haben NULL.

Das Standardmuster ist:

newbuffer = realloc(buffer, newsize);
if (newbuffer == NULL)
{
    //handle error
    return ...
}
buffer = newbuffer;

Beachten Sie auch, dass das Casting den Rückgabewert ausmacht malloc ist unnötig in C und das sizeof(char) ist per definitionem gleich 1.

  • Warum kannst du nicht buffer = realloc(buffer, newsize); ?

    – ylun.ca

    1. Oktober 2015 um 17:03 Uhr

  • @ylun aus den in der Antwort erläuterten Gründen

    – David Heffernan

    1. Oktober 2015 um 18:25 Uhr

  • Richtig, um Datenverlust zu vermeiden, sollten Sie zuerst überprüfen, ob die Zuordnung erfolgreich ist, und dann erneut zuweisen, danke.

    – ylun.ca

    1. Oktober 2015 um 18:35 Uhr

  • Was passiert, wenn Sie einen kleineren Speicherblock neu zuweisen?

    – Kenny Worden

    30. April 2017 um 21:00 Uhr

  • Offensichtlich verlieren Sie, was Sie freigeben, aber Sie behalten den Rest

    – David Heffernan

    30. April 2017 um 21:01 Uhr

Benutzeravatar von pmg
pmg

Nichts geht verloren. Aber man sollte wirklich testen, ob das der Fall ist realloc() (und die malloc() vorher) “funktioniert”.
Auch die Umwandlung in den Rückgabewert von malloc ist bestenfalls redundant und kann einen Fehler verbergen, den der Compiler ohne seine Abwesenheit entdeckt hätte.

basierend auf der Annahme, dass Sie Zeichenfolgen möchten, Ihre Verwendung von strncpy ist falsch

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char *buffer = malloc(3);
    if (buffer == NULL) /* no memory */ exit(EXIT_FAILURE);

    strncpy(buffer, "AB", 2);
    /* ATTENTTION! ATTENTION: your array is not a string.
    ** buffer[2] is not the zero string terminator */

    // buffer = realloc(buffer, 6); /* Will there be any lost here? */
    /* If realloc returns NULL, you've just lost the only pointer to
    ** the allocalted memory, by overwriting it with NULL.
    ** Always `realloc` to a temporary variable */
    char *tmp_buffer = realloc(buffer, 6);
    if (tmp_buffer == NULL) {
        /* realloc failed */
    } else {
        /* realloc worked, no bytes lost */
        buffer = tmp_buffer;
        /* ATTENTION! ATTENTION: buffer is still not a string
        ** buffer[0] is 'A', buffer[1] is 'B',
        ** all other elements of buffer are indeterminate */
    }

    free(buffer);
    return(0);
}

1395480cookie-checkVerlieren wir Daten in einem Puffer nach der Neuzuweisung?

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

Privacy policy