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);
}
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.
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
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);
}
13954800cookie-checkVerlieren wir Daten in einem Puffer nach der Neuzuweisung?yes