Gast
#4991933
Hallo, ist diese Speicherreservieren so wie hier gezeigt mit malloc korrekt?
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
|
Anzeige
|
Speicher reservieren mit malloc
Gast
#4991933
Hallo, ist diese Speicherreservieren so wie hier gezeigt mit malloc korrekt?
Gast
#4991947
Jo schrieb: > so wie hier gezeigt mit malloc korrekt? Du musst noch pruefen, ob du auch speicher bekommen hast.
Ansonsten passt das. Bei
scheiden sich die Geister, ob man den Rueckgabewert von malloc nun casten sollte oder nicht. In C++ musst du casten, in C kannst du casten, musst du aber nicht. Beachte, dass bei malloc der Speicher nicht initialisiert wird! Wenn du calloc benutzt, dann wird der Speicher mit 0 initialisiert. http://www.cplusplus.com/reference/cstdlib/calloc/
Gast
#4991966
Ok dann vielen Dank! Jo schrieb: > ist diese Speicherreservieren so wie hier gezeigt mit malloc korrekt? ich würde folgendes bevorzugen:
Grund: wenn du den Pointertyp von "ptr_test" änderst, musst du bei meiner Variante das Malloc nicht anpassen - kannst es also auch nicht vergessen. bezüglich: Kaj schrieb: > scheiden sich die Geister, ob man den Rueckgabewert von malloc nun > casten sollte oder nicht. In C++ musst du casten, in C kannst du casten, > musst du aber nicht. in c++ könnte man aber auch direkt `new` benutzen - außer es kümmern sich C Funktionen um die Freigabe, dann ist die Ressourcenallokation allerdings asymetrisch und das SW-Design doof.
Gast
#4992114
Vlad T. schrieb: >> scheiden sich die Geister, ob man den Rueckgabewert von malloc nun >> casten sollte oder nicht. In C++ musst du casten, in C kannst du casten, >> musst du aber nicht. > > in c++ könnte man aber auch direkt `new` benutzen - außer es kümmern > sich C Funktionen um die Freigabe, dann ist die Ressourcenallokation > allerdings asymetrisch und das SW-Design doof. Beim casten sollte man aber C++ style casts benutzen und raw pointer auf selbst reservierten space vermeiden (und kein delete). Kaj schrieb: > Bei > ptr_test = (test*)malloc(sizeof(test)); > scheiden sich die Geister, ob man den Rueckgabewert von malloc nun > casten sollte oder nicht. In C++ musst du casten, in C kannst du casten, > musst du aber nicht. In C ist der Cast vollkommen unnötig. Wenn man aber vergisst, den nötigen Header einzubinden, nimmt der Compielr an, dass malloc int zurückgibt. Ohne den Cast kommt dann eine Warnung. Mit Cast bleibt der Compiler ruhig, da du mit dem Cast sagst, dass du die Konvertierung so willst. Das ist der Grund, warum die meisten dazu raten, den Cast nicht hinzuschreiben - er kann einen Fehler verstecken. Vlad T. schrieb: > in c++ könnte man aber auch direkt `new` benutzen - außer es kümmern > sich C Funktionen um die Freigabe, dann ist die Ressourcenallokation > allerdings asymetrisch und das SW-Design doof. Das Design ist dann einfach kaputt und gehört repariert.
Gast
#4993653
Später das free nicht vergessen! Kaj schrieb: > Jo schrieb: >> so wie hier gezeigt mit malloc korrekt? > Du musst noch pruefen, ob du auch speicher bekommen hast. >
Wenn das nicht gerade irgendwas spezielles sicherheitskritisches ist, oder was was gigantische Matritzen auf einem Supercomputer multipliziert, ist das ziemlich sinnlos. Es macht den Code extrem schwer zu lesen, wenn nach jedem alloc ein if ( !x ) return ist, es ist sehr sehr schwer das insgesamt so hinzubekommen dass es sich sinnvoll verhält wenn der Speicher voll ist, und auf Systemen wie Linux kommt von malloc eh nie 0 zurück selbst wenn es keinen Speicher gibt. Dazu sind deine Optionen zur Fehlerbehandlung sehr beschränkt in den meisten Programmen, und ob du dann exit(0) machst oder einfach das null dereferenzierst ist ziemlich wurscht. Sven B. schrieb: > und auf Systemen wie Linux kommt von malloc > eh nie 0 zurück selbst wenn es keinen Speicher gibt. Ich nutze linux und habe dass bereits gesehen. Dass passiert beispielsweise, wenn man versucht mehr Speicher zu reservieren als ram & swap verfügbar sind (es gibt jedoch die möglichkeit dieses verhalten auszuschalten). Wenn der Kernel speicher braucht, und es gibt keinen mehr, kommt dann der OOM-Killer und schiesst die speicherhungrigste Anwendung ab. Das kann z.B. passieren, wenn eine Page mit reserviertem Speicher zum ersten mal genutzt wird, wobei der Kernel erst zu dem Zeitpunkt versucht den speicher dafür tatsächlich zu reservieren.
Beitrag #4994061 wurde von einem Moderator gelöscht.
Sven B. schrieb: > Wenn das nicht gerade irgendwas spezielles sicherheitskritisches ist, > oder was was gigantische Matritzen auf einem Supercomputer > multipliziert, ist das ziemlich sinnlos. Es macht den Code extrem schwer > zu lesen, wenn nach jedem alloc ein if ( !x ) return ist, es ist sehr > sehr schwer das insgesamt so hinzubekommen dass es sich sinnvoll verhält > wenn der Speicher voll ist, Sehe ich nicht so. Was ist an dem Code if(ptr == NULL) denn schwer verständlich? Es ist aus meiner Sicht gar keine Option den Fehler nicht abzufangen, denn sonst wird je nach OS das Programm irgendwann beim Zugriff beendet, wo es evt. sehr ungünstig ist. Je nach Funktionalität die den Speicher brauch, muss man halt entsprechende Ersatzmaßnahmen einleiten. Evt. ist das malloc nur für ein optionales Feature gedacht und darf nicht gleich zum kill des ganzen Programms führen... Gerade im Embedded-Bereich kann das böse enden! Daniel A. schrieb: > Ich nutze linux und habe dass bereits gesehen. Dass passiert > beispielsweise, wenn man versucht mehr Speicher zu reservieren als ram & > swap verfügbar sind (es gibt jedoch die möglichkeit dieses verhalten > auszuschalten). Wenn der Kernel speicher braucht, und es gibt keinen > mehr, kommt dann der OOM-Killer und schiesst die speicherhungrigste > Anwendung ab. Das kann z.B. passieren, wenn eine Page mit reserviertem > Speicher zum ersten mal genutzt wird, wobei der Kernel erst zu dem > Zeitpunkt versucht den speicher dafür tatsächlich zu reservieren. Ja, hast du im Detail natürlich recht, und man kann das overcommit auch per sysctl ausschalten. Aber wenn einfach nur der Speicher voll ist, kommt i.d.R. kein null zurück. Das typische "mein Programm reserviert zu viel Speicher weil Endlosschleife oder Leak"-Problem kriegst du damit nicht. > Bloß weil du keine Ahnung hast, heißt es nicht, dass fehlertolerante > Programmierung sinnlos wäre. Es gibt viele Stellen, an denen defensive Programmierung hilfreich ist, aber nicht beim Speicher reservieren in der typischen Userspace-Anwendung. Das macht auch kein Mensch, weil es wie gesagt alles mit diesen Checks vollrümpelt und die Checks in den meisten Situationen sowieso nix machen können außer exit. Ich habe mal hier bei $anwendung mit ~150k SLOC gegreppt, es gibt 2449 memory allocations; wenn ich bei jeder ein if ( !x ) { return } dahinter baue, habe ich schon 7500 Zeilen Code produziert die das absolute Minimum sind, um sinnvoll zu reagieren, aber in der Form noch absolut gar nichts bringen. Im Gegenteil, die produzieren nur noch wirrere Fehlersituationen wenn eine davon tatsächlich auslöst. > Sehe ich nicht so. Was ist an dem Code if(ptr == NULL) denn schwer > verständlich? Der Code ist verständlich, aber es wird wahnsinnig viel davon werden für sehr wenig Gewinn. > Es ist aus meiner Sicht gar keine Option den Fehler nicht > abzufangen, denn sonst wird je nach OS das Programm irgendwann beim > Zugriff beendet, wo es evt. sehr ungünstig ist. Pff, Pech, dann ist es halt weg. Viel mehr kannst du mit deinem Check auch nicht machen. :D Meines Erachtens ist das wirklich an der völlig falschen Stelle auf irgendeine "Sauberkeit" auf dem Papier geachtet und als Tipp gerade für Anfänger sehr unpassend. Die Software mit der man in der Praxis konfrontiert wird, stürzt ab, weil man in der "falschen" Reihenfolge auf zwei Buttons klickt. Da hätte man mal defensiv programmieren sollen, nicht bei der memory allocation. Sven B. schrieb: > Aber wenn einfach nur der Speicher voll ist, > kommt i.d.R. kein null zurück. Das typische "mein Programm reserviert zu > viel Speicher weil Endlosschleife oder Leak"-Problem kriegst du damit > nicht. Folgenden Code hat jedenfalls unter Linux meinen Speicher gefüllt, bis malloc NULL retournierte:
Sven B. schrieb: >> Es ist aus meiner Sicht gar keine Option den Fehler nicht >> abzufangen, denn sonst wird je nach OS das Programm irgendwann beim >> Zugriff beendet, wo es evt. sehr ungünstig ist. > Pff, Pech, dann ist es halt weg. Viel mehr kannst du mit deinem Check > auch nicht machen. :D Meine Meinung: Lieber ein definiertes Verhalten mit exit, bei dem vorher evt. noch irgendwelche Daten gesichert werden können, als NULL zu dereferenzieren. Hängt halt immer von der Situation ab, welche Aktion die sinnvollste ist. Be S. schrieb: > Sven B. schrieb: >> Aber wenn einfach nur der Speicher voll ist, >> kommt i.d.R. kein null zurück. Das typische "mein Programm reserviert zu >> viel Speicher weil Endlosschleife oder Leak"-Problem kriegst du damit >> nicht. > > Folgenden Code hat jedenfalls unter Linux meinen Speicher gefüllt, bis > malloc NULL retournierte: Bei mir nicht.
SIGKILL -> OOM killer ... Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|