realloc()
-
Hi,
Der Standard - 7.20.3.4 The realloc function | schrieb:
[..]
If memory for the new object cannot be allocated, the old object is not deallocated and its value is unchanged.
[..]
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.
Daraus schließe ich, dass die einzig "ordentliche" Methode realloc() zu verwenden so aussehen muss:
void *temp = realloc(p, size); if (!temp) .. ..
Da man sonst p verlieren könnte und man den Speicher somit nicht mehr freigeben kann.
Sehe ich das richtig?Wie gebt ihr euren Speicher wieder frei? Angenommen man hat ein Programm:
int main() { malloc() malloc() malloc() // Hier geht was schief, das Programm soll beendet werden. // exit() ohne free() scheint unschön, goto aber auch. // Eine extra Funktion dafür ist auch sehr unpraktikabel. // Programm free() free() free() return 0; }
Momentan scheint mir tatsächlich goto die beste Lösung dafür zu sein..
-
int main() { a = malloc() b = malloc() c = malloc() // Hier geht was schief, das Programm soll beendet werden. // exit() ohne free() scheint unschön, goto aber auch. // Eine extra Funktion dafür ist auch sehr unpraktikabel. if(a && b && c) // Programm free(a) free(b) free(c) return 0; }
Da man free auch NULL übergeben kann, führt das z.b. zu keinem Problem.
-
Ok, das wäre für das einfache Beispiel natürlich eine Lösung. Aber wie sieht's aus wenn man auch innerhalb von "//programm" und in Schleifen auf malloc() etc. angewiesen ist?
-
Blubb? Gibt's da keine elegante Lösung?
-
Irgendwann (Programmende) musst du den Speicher doch eh freigeben. Da hast du dann deine Funktion.
-
DirkB schrieb:
Irgendwann (Programmende) musst du den Speicher doch eh freigeben. Da hast du dann deine Funktion.
Ich weiß nicht, wie du das meinst. Es geht darum, wie man das Programm abbricht. Wie gesagt, mit Goto ans Programmende springen und immer schön alles mit Nullzeigern initialisieren wäre auch meine erste Idee, aber das gute Goto wird ja von einigen hier nicht so gemocht.
-
Es gibt auch noch
atexit()
. Da kann man Funktionen angeben, die beim Programmende aufgerufen werden sollen.
-
cooky451 schrieb:
Daraus schließe ich, dass die einzig "ordentliche" Methode realloc() zu verwenden so aussehen muss:
void *temp = realloc(p, size); if (!temp) .. ..
Da man sonst p verlieren könnte und man den Speicher somit nicht mehr freigeben kann.
Sehe ich das richtig?Das ist richtig.
cooky451 schrieb:
Momentan scheint mir tatsächlich goto die beste Lösung dafür zu sein..
Es gibt in C in der Tat eine Denkschule, die goto für diesen Zweck für angemessen hält - nicht nur für Speicher-, sondern für Ressourcenfreigabe generell (fopen/fclose zum Beispiel). Ich persönlich finde das zwar äußerst unschön und unübersichtlich, aber eine andere allgemeine Lösung für das Problem ist mir in C nicht bekannt.
Meistens ist meine Lösung, den Code statt in C in C++ zu schreiben, wo man RAII betreiben kann. Wenn das nicht geht, entscheide ich das nähere Vorgehen je nach Einzelfall. Dass free(NULL);, wie feigling~ richtig anspricht, nichts macht und gefahrlos durchläuft, ist dabei ein wichtiger Baustein, mit dem sich die Problematik in der Regel elegant umschiffen lässt. Das angesprochene Beispiel lässt sich ja auch gut schachteln - solange man darauf achtet, dass der einzige Punkt, an dem die Funktion verlassen werden kann, ihr Ende ist, sehe ich da eigentlich kein Problem.
-
Professionelle Lösungen arbeiten mit eigenen Memorymanagern, da reicht dann meist ein Quasi-Destruktor/free aus, üblicherweise mit atexit bzw. longjmp.
alloca gibt es auch noch, ist aber kein ANSI C.
-
DirkB schrieb:
Es gibt auch noch
atexit()
.Kenne ich, aber die muss ja erst mal an die Zeiger kommen. (Und globale Variablen gehen natürlich nicht.)
seldon schrieb:
Meistens ist meine Lösung, den Code statt in C in C++ zu schreiben
Du glaubst gar nicht wie sehr ich C++ gerade vermisse.
seldon schrieb:
Das angesprochene Beispiel lässt sich ja auch gut schachteln
Hilft mir leider nicht so sehr, da das bei mir nicht möglich ist.
Wutz schrieb:
Professionelle Lösungen arbeiten mit eigenen Memorymanagern
Ich weiß zwar nicht mal, ob du das gemeint hast, aber es hat mich trotzdem auf eine Idee gebracht. Ich bastel mir einfach eine Liste, mal gucken ob das funktioniert.
-
was hält dich davon ab goto zu benutzen, nur weil in den papagai-schulen gelehrt wird, dass es böse ist?
gerade bei aufräumarbeiten am ende von funktionen lässt es sich wunderbar einsetzten und macht den code schön überschitlich und lesbar.
-
B.B. schrieb:
was hält dich davon ab goto zu benutzen, nur weil in den papagai-schulen gelehrt wird, dass es böse ist?
gerade bei aufräumarbeiten am ende von funktionen lässt es sich wunderbar einsetzten und macht den code schön überschitlich und lesbar.Unter anderem solche Leute wie du, die Ratschläge und Einschätzungen über andere Leute vergeben und dabei noch nicht mal in der Lage sind, ihre Worte orthografisch richtig zu formulieren.
Papagei schreibt man Papagei und nicht Papagai.
-
Orthografisch formulieren?
Außerdem hat B.B. weitgehend recht, trotz des falschen Buchstabens.
-
B.B. schrieb:
was hält dich davon ab goto zu benutzen, nur weil in den papagai-schulen gelehrt wird, dass es böse ist?
Weil es Projekte gibt, die von genau diesen Papagei-Schulen bewertet werden.
Abgesehen davon wäre es aber in meinem Fall tatsächlich nicht (mehr) sinnvoll.