Allokierten Speicher freigeben: realloc() vs. free()

Lesezeit: 7 Minuten

Benutzeravatar von user3021085
Benutzer3021085

also habe ich ein stück speicher mit allokiert malloc() und später mit geändert realloc().

Irgendwann in meinem Code möchte ich es leeren, damit meine ich im Wesentlichen, ihm eine Erinnerung an 0 zu geben. Etwas, das intuitiv erledigt werden würde realloc(pointer,0). Ich habe hier gelesen, dass dies implementierungsdefiniert ist und nicht verwendet werden sollte.

Sollte ich stattdessen verwenden free()und dann noch eins malloc()?

  • Was meinst du mit “leeren”?

    – Oliver Charlesworth

    10. Februar 2014 um 9:12 Uhr

Benutzeravatar von Elias Van Ootegem
Elias Van Ootegem

Es kommt darauf an, was Sie meinen: wenn Sie wollen Leeren Sie den verwendeten Speicheraber immer noch Zugriff auf diesen Speicher haben, dann verwenden Sie memset(pointer, 0, mem_size);um den Speicher auf Nullen neu zu initialisieren.
Benötigen Sie diesen Speicher nicht mehr, dann rufen Sie einfach an free(pointer);wodurch der Speicher freigegeben wird, sodass er anderweitig verwendet werden kann.

Verwenden realloc(pointer, 0) kann wie funktionieren free auf Ihrem System, aber das ist nicht Standardverhalten. realloc(ptr, 0) wird von den C99- oder C11-Standards nicht als Äquivalent zu spezifiziert free(ptr).

realloc(pointer, 0) ist nicht gleichbedeutend mit free(pointer).

Der Standard (C99, §7.22.3.5):

The realloc function
Synopsis
1
#include <stdlib.h>
void *realloc(void *ptr, size_t size);

Description
2 The realloc function deallocates the old object pointed to by ptr and returns a
pointer to a new object that has the size specified by size. The contents of the new
object shall be the same as that of the old object prior to deallocation, up to the lesser of
the new and old sizes. Any bytes in the new object beyond the size of the old object have
indeterminate values.
3 If ptr is a null pointer, the realloc function behaves like the malloc function for the
specified size. Otherwise, if ptr does not match a pointer earlier returned by a memory
management function, or if the space has been deallocated by a call to the free or
realloc function, the behavior is undefined. If memory for the new object cannot be
allocated, the old object is not deallocated and its value is unchanged.
Returns
4
The realloc function returns a pointer to the new object (which may have the same
value as a pointer to the old object), or a null pointer if the new object could not be
allocated.

Wie Sie sehen können, gibt es keinen Sonderfall für realloc-Aufrufe an, bei denen die Größe 0 ist. Stattdessen gibt es nur an, dass ein NULL-Zeiger zurückgegeben wird, wenn kein Speicher zugewiesen werden kann, und ein Zeiger in allen anderen Fällen. Ein Zeiger, der auf 0 Bytes zeigt, wäre dann eine praktikable Option.

Um eine verwandte Frage zu zitieren:

Intuitiv ist realloc “konzeptionell äquivalent” zu malloc+memcpy+free auf dem anderen Zeiger, und Mallocing eines 0-Byte-Speicherblocks gibt entweder NULL oder einen eindeutigen Zeiger zurück, der nicht zum Speichern von irgendetwas verwendet werden soll (Sie haben gefragt für 0 Byte), aber noch freizugeben. Also, nein, verwenden Sie realloc nicht so, es kann bei einigen Implementierungen (nämlich Linux) funktionieren, aber es ist sicherlich nicht garantiert.

Als eine andere Antwort auf diese verknüpfte Frage heißt es, das Verhalten von realloc(ptr, 0) ist explizit definiert als Umsetzung definiert nach aktuellem C11-Standard:

Wenn die Größe des angeforderten Speicherplatzes Null ist, ist das Verhalten implementierungsdefiniert: Entweder wird ein Nullzeiger zurückgegeben, oder das Verhalten ist so, als ob die Größe ein Wert ungleich Null wäre, außer dass der zurückgegebene Zeiger nicht verwendet werden soll, um auf ein Objekt zuzugreifen

  • thx das ist was ich wollte, ich möchte zu einem späteren Zeitpunkt wieder neu zuordnen können

    – Benutzer3021085

    10. Februar 2014 um 9:33 Uhr

  • @ user3021085: Sie sollten so viel Speicher wie möglich freigeben, während Sie dennoch sicher sein können, den Zeiger zu behalten, indem Sie verwenden realloc(pointer, 1)das würde fast den gesamten Speicher freigeben, und Sie hätten immer noch einen Zeiger bereit

    – Elias Van Ootegem

    10. Februar 2014 um 9:48 Uhr

  • Ja, aber ich habe einige Informationen, die ich überprüfe. Wenn ich 1 zuweise, bekomme ich möglicherweise undefiniertes Verhalten

    – Benutzer3021085

    10. Februar 2014 um 11:04 Uhr

  • @user3021085: Dann einfach verwenden realloc(pointer, sizeof *pointer)… Ich kann nicht sehen, wie das zu einem undefinierten Verhalten führen würde …

    – Elias Van Ootegem

    10. Februar 2014 um 11:10 Uhr

  • Dies war im C89/C90-Standard der Fall. Befreien Sie es mit realloc(pointer,0) war damals Pflicht. Ich würde argumentieren, dass es zwingend erforderlich ist, es in den neueren C- und POSIX-Standards nicht freizugeben.

    – 12431234123412341234123

    4. Januar 2021 um 18:32 Uhr

Der Benutzeravatar von G
Gegangen

realloc() wird verwendet, um den Speicher zu vergrößern oder zu verkleinern und nicht, um den Speicher freizugeben.

Überprüfen Sie diesund verwenden free() um die Erinnerung freizugeben (Verknüpfung).

Benutzeravatar von unwind
entspannen

Ich glaube nicht, dass Sie “leer” meinen; das würde bedeuten “auf einen bestimmten Wert setzen, den ich für leer halte” (oft alle Bits Null). Sie meinen frei oder freigeben.

Die Handbuchseite sagt:

Wenn ptr ist NULLdann ist der Aufruf gleichbedeutend mit malloc(size)für alle Werte von size; wenn size gleich Null ist, und ptr ist nicht NULLdann ist der Aufruf gleichbedeutend mit free(ptr).

Traditionell könnten Sie verwenden realloc(ptr, 0); als Synonym für free(ptr);so wie Sie es verwenden können realloc(NULL, size); als Synonym für malloc(size);. Ich würde es jedoch nicht empfehlen, es ist ein bisschen verwirrend und nicht so, wie die Leute es erwarten.

Jedochheutzutage hat sich in modernem C die Definition geändert: jetzt realloc(ptr, 0); wird den alten Speicher freigeben, aber es ist nicht genau definiert, was als nächstes getan wird: Es ist implementierungsdefiniert.

Also: tu das nicht: benutze free() Speicher freigeben und lassen realloc() verwendet werden nur um die Größe auf etwas ungleich Null zu ändern.

  • Auf diese Weise zu verwenden realloc() scheint veraltet zu sein. Bitte schau dir meine Antwort an.

    – alk

    10. Februar 2014 um 9:25 Uhr

  • @alk Ja, es scheint weniger klar geworden zu sein. Ich habe bearbeitet, danke.

    – abschalten

    10. Februar 2014 um 9:33 Uhr

  • “jetzt realloc(ptr, 0); wird den alten Speicher freigeben, aber es ist nicht genau definiert, was als nächstes getan wird: es ist implementierungsdefiniert.” – Ich bin mir nicht sicher, ob das richtig ist. Wenn realloc kehrt zurück NULLdann weist dies auf einen Zuordnungsfehler hin, und bei einem Zuordnungsfehler wird der alte Speicher nicht freigegeben.

    Benutzer743382

    10. Februar 2014 um 10:18 Uhr

Benutzeravatar von alk
alk

Verwenden free() freigeben, um dynamisch zugewiesenen Speicher freizugeben.

Obwohl frühere Dokumentationen dies besagen realloc(p, 0) ist äquivalent zu free(p)das Neueste POSIX-Dokumentation ausdrücklich, dass dies nicht der Fall ist:

Frühere Versionen erlaubten ausdrücklich einen Aufruf von realloc (p, 0), um den Speicherplatz freizugeben, auf den p zeigt, und einen Nullzeiger zurückzugeben. Obwohl dieses Verhalten als von dieser Version des Standards zugelassen interpretiert werden könnte, hat das C-Sprachkomitee darauf hingewiesen, dass diese Interpretation falsch ist.

Und mehr noch:

Anwendungen sollten davon ausgehen, dass der Speicherplatz, auf den p zeigt, nicht freigegeben wurde, wenn realloc() einen Nullzeiger zurückgibt.

Verwenden free(pointer); pointer = 0 Anstatt von realloc(pointer, 0).

Benutzeravatar von Soumen
Soumen

void* realloc (void* ptr, size_t size);

Im C90:

wenn size Null ist, wird der zuvor bei ptr zugewiesene Speicher freigegeben, als ob ein Aufruf von free durchgeführt worden wäre, und ein Nullzeiger wird zurückgegeben.

In C99:

Wenn size Null ist, hängt der Rückgabewert von der jeweiligen Bibliotheksimplementierung ab: Es kann entweder ein Nullzeiger oder eine andere Stelle sein, die nicht dereferenziert werden soll.

Benutzeravatar von Trouble-lling
Problemlösung

Ich würde realloc verwenden, um einem Zeiger mehr oder weniger Speicher zu geben, aber nicht, um ihn zu leeren. Um den Zeiger zu leeren, würde ich kostenlos verwenden.

  • leeren” Ein Zeiger ist kein gebräuchlicher Ausdruck (zumindest nicht im Kontext der C-Programmierung). Außerdem ist er irreführend und passt nicht dazu, was wann passiert free()Indem der Speicher, auf den ein Zeiger verweist, zeigt.

    – alk

    10. Februar 2014 um 9:15 Uhr


1437470cookie-checkAllokierten Speicher freigeben: realloc() vs. free()

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

Privacy policy