Von man realloc: Die Funktion realloc() gibt einen Zeiger auf den neu zugewiesenen Speicher zurück, der für jede Art von Variable geeignet ausgerichtet ist und vielleicht anders als ptr, oder NULL, wenn die Anfrage fehlschlägt.
Also in diesem Codeschnipsel:
ptr = (int *) malloc(sizeof(int));
ptr1 = (int *) realloc(ptr, count * sizeof(int));
if(ptr1 == NULL){ //reallocated pointer ptr1
printf("Exiting!!\n");
free(ptr);
exit(0);
}else{
free(ptr); //to deallocate the previous memory block pointed by ptr so as not to leave orphaned blocks of memory when ptr=ptr1 executes and ptr moves on to another block
ptr = ptr1; //deallocation using free has been done assuming that ptr and ptr1 do not point to the same address
}
Reicht es aus, einfach anzunehmen, dass der neu zugewiesene Zeiger auf einen anderen Speicherblock zeigt und nicht auf denselben Block? ausführt (aus dem in den Kommentaren angegebenen Grund), dann würde der Speicherblock gelöscht und das Programm würde verrückt werden. Soll ich eine andere Bedingung einfügen, die die Gleichheit von ptr und ptr1 vergleicht und die Ausführung der free(ptr)-Anweisung ausschließt?
Aaron S. Kurland
Nur nicht anrufen free() auf deinem ursprünglichen ptr auf dem glücklichen weg. Im Wesentlichen realloc() hat das für dich erledigt.
ptr = malloc(sizeof(int));
ptr1 = realloc(ptr, count * sizeof(int));
if (ptr1 == NULL) // reallocated pointer ptr1
{
printf("\nExiting!!");
free(ptr);
exit(0);
}
else
{
ptr = ptr1; // the reallocation succeeded, we can overwrite our original pointer now
}
In der Manpage von realloc konnte ich die Information nicht finden, dass es selbst free() aufrufen würde … thnx sowieso
– Benutzer3163420
8. Januar 2014 um 21:32 Uhr
@ user3163420 Wirklich? Auf meinem Mac man realloc: “… Wenn nicht genug Platz vorhanden ist, um die Speicherzuweisung zu vergrößern, auf die ptr zeigt, erstellt realloc() eine neue Zuweisung, kopiert so viele der alten Daten, auf die ptr zeigt, wie in die neue Zuweisung passen, gibt die alte Zuweisung und gibt einen Zeiger auf den zugewiesenen Speicher zurück. …”
– Bedeutungsangelegenheiten
8. Januar 2014 um 21:34 Uhr
Gießen Sie nicht das Ergebnis von malloc und realloc.
– Emlai
28. September 2015 um 10:39 Uhr
heh … die Typumwandlungen sind nicht nur ein Dorn im Auge, sondern könnten auf einigen obskuren Systemen Probleme verursachen und keinen Zweck erfüllen … aber Sie haben sie beibehalten, um den ursprünglichen Code zu erhalten. Jetzt wurden Leerzeichen eingeführt, um es weniger zu einem Schandfleck zu machen, die auch keinen funktionalen Zweck erfüllen, aber nichts kaputt machen (im Gegensatz zu Typumwandlungen, die dies tun werden). Mein Punkt ist, ob Sie zulassen würden, dass Leerzeichen hinzugefügt werden, um den Code zu erstellen stilistisch ansprechendwürden Sie auch zulassen, dass unnötige Typumwandlungen entfernt werden, um den Code zu erstellen tragbarer zusätzlich zu stilistisch ansprechend? Ich werde nicht bearbeiten, aber würdest du zurückgehen, wenn ich es täte?
– autistisch
29. April 2018 um 15:22 Uhr
/me schreit “Onkel!”. Abgüsse entfernt.
– Aaron S. Kurland
8. August 2018 um 15:32 Uhr
Kieler
Anwenden von Korrekturen als Bearbeitungen, basierend auf den guten Kommentaren unten.
“Wenn es dazu in der Lage ist, gibt es Ihnen einfach denselben Zeiger zurück, den Sie ihm gegeben haben.”
“Aber wenn es zu einem anderen Teil des Speichers gehen muss, um genügend zusammenhängenden Platz zu finden, wird es einen anderen Zeiger zurückgeben (und der vorherige Zeigerwert wird unbrauchbar).”
“Wenn realloc kann überhaupt nicht genug Platz finden, gibt es einen Nullzeiger zurück und lässt die vorherige Region zugewiesen.”
Dies kann direkt in Code übersetzt werden:
int* ptr = (int*)malloc(sizeof(int));
int* tmp = (int*)realloc(ptr, count * sizeof(int));
if(tmp == NULL)
{
// Case 3, clean up then terminate.
free(ptr);
exit(0);
}
else if(tmp == ptr)
{
// Case 1: They point to the same place, so technically we can get away with
// doing nothing.
// Just to be safe, I'll assign NULL to tmp to avoid a dangling pointer.
tmp = NULL;
}
else
{
// Case 2: Now tmp is a different chunk of memory.
ptr = tmp;
tmp = NULL;
}
Wenn Sie also darüber nachdenken, ist der von Ihnen gepostete Code (fast) in Ordnung. Der obige Code vereinfacht sich zu:
Beachten Sie das Extra else if(ptr != tmp)was Fall 1 ausschließt, in dem Sie nicht anrufen möchten free(ptr) Weil ptr und tmp beziehen sich auf die gleiche Stelle. Nur zur Sicherheit stelle ich sicher, dass ich zuweise NULL zu tmp um Probleme mit baumelnden Zeigern zu vermeiden tmp liegt im Geltungsbereich.
Sie haben den Teil “und der vorherige Zeigerwert wird unbrauchbar” nicht befolgt. In dem ptr != tmp Fall, der free(ptr) ist falsch.
– glglgl
19. Juni 2017 um 15:28 Uhr
Stimme @glglgl zu, dass diese Antwort gefährlich ist, da du in Fall 2 nicht free(ptr) anrufen darfst.
– Benutzer7761803
5. September 2017 um 13:35 Uhr
Guter Anruf, angewendet als Bearbeitung und Kommentar-Upvotes für Sie beide.
– Kieler
5. September 2017 um 22:14 Uhr
@Keeler +1 zum Setzen des tmp-Zeigers auf NULL. Ich bin nur schwer gebissen worden, als ich einen neu zugewiesenen Zeiger innerhalb einer Funktion in statisch geändert habe. Das verursachte einen späteren Segfault mit nachfolgenden Realloc-Aufrufen (Speicher wurde zwischen Funktionsaufrufen freigegeben), da der Zeiger jetzt seinen alten (hängenden) Wert behielt. Ich habe eine Weile gebraucht, um es herauszufinden … Ich habe die Angewohnheit, Realloc oft über Malloc zu verwenden, aber man muss wachsam sein, um sicherzustellen, dass der erste Realloc-Aufruf (ohne vorheriges Malloc) einen NULL-Zeiger erhält.
– DeutscherNerd
21. März 2019 um 9:26 Uhr
Ich denke, dass exit(1) hier besser geeignet wäre.
– Herr
23. April um 15:28 Uhr
Chux – Wiedereinsetzung von Monica
OP: … kann sich von ptr unterscheiden oder NULL sein, wenn die Anfrage fehlschlägt.
A: Nicht immer. NULL kann rechtmäßig zurückgegeben werden (kein Fehler), wenn count ist 0.
OP: Reicht es aus, einfach anzunehmen, dass der neu zugewiesene Zeiger auf einen anderen Speicherblock und nicht auf denselben Block zeigt.
A: Nein
OP: Soll ich eine andere Bedingung einfügen, die die Gleichheit von ptr und ptr1 vergleicht und die Ausführung der free(ptr)-Anweisung ausschließt?
A: Nein.
Wenn realloc() kehrt zurück NULL (und count ist nicht 0), der Wert von ptr ist immer noch gültig und zeigt auf die nicht in der Größe geänderten Daten. free(ptr) oder nicht, hängt von Ihren Zielen ab.
Wenn realloc() kehrt nicht zurück NULLunterlassen Sie free(ptr)es ist alles bereit befreit.
realloc wird dieselbe Adresse zurücksenden ptr wenn es genug Platz hat, um den eigentlichen Speicherbereich zu erweitern, auf den verwiesen wird ptr. Andernfalls werden die Daten in den neuen Chunk verschoben und der alte Chunk freigegeben. Darauf kann man sich nicht verlassen ptr1 anders zu sein ptr. Ihr Programm verhält sich undefiniert.
Wenn realloc eine andere Adresse zurückgibt, wird zuerst die Zuordnung der alten aufgehoben, sodass Sie dies nicht selbst tun müssen.
Übrigens, werfen Sie niemals die Rückkehr von malloc/realloc :). Ihr Code sollte so aussehen:
ptr=malloc(sizeof(int));
ptr=realloc(ptr,count*sizeof(int));
if(ptr==NULL)
{
// error!
printf("\nExiting!!");
// no need to free, the process is exiting :)
exit(0);
}
Wenn realloc Ihre Daten verschiebt, wird der alte Zeiger hinter den Kulissen für Sie freigegeben. Ich habe keine Kopie des C11-Standards, aber es ist im C99-Standard garantiert.
Der C11-Standardentwurf ist n1570.pdf, den Sie durch googeln finden können. Ich finde es hilfreich, mit Links zu zitieren (z Klicken Sie auf diesen Link bringt Sie zum realloc Abschnitt von n1570.html, der aus n1570.pdf konvertiert wurde).
– autistisch
2. Januar 2016 um 22:39 Uhr
Johannes Bode
Du solltest nichtfree Ihr ursprünglicher Zeiger, wenn die realloc gelingt es. Ob sie free dieser Zeiger, wenn die realloc fehlschlägt, hängt von den Anforderungen Ihrer speziellen Anwendung ab; wenn du absolut nicht weitermachen Ohne diesen zusätzlichen Speicher wäre dies ein schwerwiegender Fehler und Sie würden den gehaltenen Speicher freigeben und beenden. Wenn Sie, OTOH, immer noch fortfahren können (vielleicht eine andere Operation ausführen und hoffen, dass der Speicher später verfügbar wird), möchten Sie wahrscheinlich an diesem Speicher festhalten und einen anderen versuchen realloc später.
2 Die realloc Funktion hebt das alte Objekt auf darauf hingewiesen von ptr und gibt einen Zeiger auf ein neues Objekt zurück, das die durch angegebene Größe hat size. Der Inhalt des neuen Objekts soll derselbe wie der des alten Objekts vor der Freigabe sein, bis auf die kleinere der neuen und alten Größen. Alle Bytes im neuen Objekt, die über die Größe des alten Objekts hinausgehen, haben unbestimmte Werte.
3 Wenn ptr ist ein Nullzeiger, der realloc Funktion verhält sich wie die malloc Funktion für die angegebene Größe. Ansonsten, wenn ptr nicht mit einem Zeiger übereinstimmt, der zuvor von einer Speicherverwaltungsfunktion zurückgegeben wurde, oder wenn der Speicherplatz durch einen Aufruf von freigegeben wurde free oder realloc Funktion, das Verhalten ist undefiniert. Wenn kein Speicher für das neue Objekt zugewiesen werden kann, wird die Zuweisung des alten Objekts nicht aufgehoben und sein Wert bleibt unverändert.
Kehrt zurück
4 Die realloc Die Funktion gibt einen Zeiger auf das neue Objekt zurück (der den gleichen Wert wie ein Zeiger auf das alte Objekt haben kann) oder einen Nullzeiger, wenn das neue Objekt nicht zugewiesen werden konnte.
Betonung hinzugefügt. Beachten Sie Abschnitt 4; Der zurückgegebene Zeiger kann mit Ihrem ursprünglichen Zeiger identisch sein.
Der C11-Standardentwurf ist n1570.pdf, den Sie durch googeln finden können. Ich finde es hilfreich, mit Links zu zitieren (z Klicken Sie auf diesen Link bringt Sie zum realloc Abschnitt von n1570.html, der aus n1570.pdf konvertiert wurde).
– autistisch
2. Januar 2016 um 22:39 Uhr
13502100cookie-checkRichtige Verwendung von realloc()yes