Cast bei malloc - securecoding.cert.org + weiteres
-
Part 1:
Als erstes die Quelle: securecoding.cert.orgDort steht ja "Immediately cast the result of a memory allocation function call into a pointer to the allocated type" (zwar als "Empfehlungen", aber trotzdem).
Nun hab ich irgendwann mal gelernt, hier im Forum wird es ja auch ständig erzählt, dass man den Rückgabewert des m/calloc-Aufrufs nicht castet, da das bei nem C-Compiler implizit geschieht (im Gegensatz zum C++).
Part 2:
Hatte letztens schon mal ein Thema (wollte es nicht noch mal aufwärmen) aufgemacht in dem um die Pointerinitialisierung nach einem free-Aufruf ging. Dort wurde gesagt, dass es nicht notwendig sei den Pointer wieder auf ein NULL zu setzen. Hier allerdings ist wieder die Empfehlung dazu.Wie vertrauenswürdig ist die Quelle, bzw. kann das jemand widerlegen? Bin gerade etwas verwirrt
-
hando schrieb:
Part 1:
Als erstes die Quelle: securecoding.cert.orgDort steht ja "Immediately cast the result of a memory allocation function call into a pointer to the allocated type" (zwar als "Empfehlungen", aber trotzdem).
Nun hab ich irgendwann mal gelernt, hier im Forum wird es ja auch ständig erzählt, dass man den Rückgabewert des m/calloc-Aufrufs nicht castet, da das bei nem C-Compiler implizit geschieht (im Gegensatz zum C++).
Part 2:
Hatte letztens schon mal ein Thema (wollte es nicht noch mal aufwärmen) aufgemacht in dem um die Pointerinitialisierung nach einem free-Aufruf ging. Dort wurde gesagt, dass es nicht notwendig sei den Pointer wieder auf ein NULL zu setzen. Hier allerdings ist wieder die Empfehlung dazu.Wie vertrauenswürdig ist die Quelle, bzw. kann das jemand widerlegen? Bin gerade etwas verwirrt
Du lieferst Deine Antworten weitgehend selbst.
-
Unterschied zwischen C und C++, guck in die FAQ hier zu dem Thema, damit dürfte klar sein, warum sich der Cast in C nicht empfiehlt.
-
Ist eine zusätzliche Sicherheitsstufe. Ein free auf einen uninitialisierten oder veralteten Pointer kann Dir den Heap komplett zersemmeln, ein free auf NULL tut gar nix. Vor allem unterstützt Du damit das Schema if(pointer) == Speicher alloziert/initialisiert, macht das Leben angenehmer. Zwingend ist das aber nicht.
-
-
Weil die Leute wiederum nur die hälfte der Strecke gedacht haben.
Der cast von malloc ist böse, weil:
int main() { int* p = (int*)malloc(2*sizeof(int)); return 0; }
abstürtzen kann.
Die korrekte Form wäre:
#include<stdlib.h> int main() { int* p = malloc(2*sizeof(*p)); return 0; }
-
PS:
achja zu free()
nur auf NULL setzen wenn der zeiger in einem validen zustand ist und so auch wieder gelöscht werden darf (bzw. neu initialisiert werden kann). idR ist das aber nicht der fall. deshalb nicht auf NULL setzen um bewusst bei einem doppelten free() den fehler zu bekommen.denn sonst hat man einen versteckten bug im code wenn ein doppeltes free gemacht wird dass nicht passieren dürfte. wenn man glück hat dann ist es ein bug ohne auswirkungen - aber meistens haben bugs auswirkungen und dann ist ein PENG besser als ein silent fail...
-
pointercrash() schrieb:
Du lieferst Deine Antworten weitgehend selbst.
-
Unterschied zwischen C und C++, guck in die FAQ hier zu dem Thema, damit dürfte klar sein, warum sich der Cast in C nicht empfiehlt.
-
Ist eine zusätzliche Sicherheitsstufe. Ein free auf einen uninitialisierten oder veralteten Pointer kann Dir den Heap komplett zersemmeln, ein free auf NULL tut gar nix. Vor allem unterstützt Du damit das Schema if(pointer) == Speicher alloziert/initialisiert, macht das Leben angenehmer. Zwingend ist das aber nicht.
Ja der Unterschied zwischen C und C++ ist deutlich klar. Nur wurde in dem obigen Link halt explizit von C, nicht C++, ausgegangen. Deshalb war es etwas verwirrend.
Shade Of Mine schrieb:
Weil die Leute wiederum nur die hälfte der Strecke gedacht haben
Das nichts damit zu tun, dass ich nur "die Hälfte der Strecke" gedacht habe. Mir war durchaus bis zu dem Zeitpunkt von vorhin bewusst, wann und wie ein Cast gefährlich sein kann. Nur halt in diesem Empfehlungen von cert.org wurde der Cast auch für C empfohlen.
Trotzdem vielen Dank soweit.
-
-
Shade Of Mine schrieb:
Der cast von malloc ist böse, weil:
int main() { int* p = (int*)malloc(2*sizeof(int)); return 0; }
abstürtzen kann.
es stürzt aber nicht wegen des casts ab, sondern weil du 'free' weggelassen hast.
zum thema: http://c-faq.com/malloc/mallocnocast.html
-
Shade Of Mine schrieb:
PS:
achja zu free()
nur auf NULL setzen wenn der zeiger in einem validen zustand ist und so auch wieder gelöscht werden darf (bzw. neu initialisiert werden kann). idR ist das aber nicht der fall. deshalb nicht auf NULL setzen um bewusst bei einem doppelten free() den fehler zu bekommen.denn sonst hat man einen versteckten bug im code wenn ein doppeltes free gemacht wird dass nicht passieren dürfte. wenn man glück hat dann ist es ein bug ohne auswirkungen - aber meistens haben bugs auswirkungen und dann ist ein PENG besser als ein silent fail...
Schon logisch, aber damit kann der Pointer nicht mehr darüber Auskunft geben, ob er mittels geglücktem malloc/realloc auf ein gültiges Speicherfleckchen zeigt.
Wenn man sich darüber unsicher ist, müßte man woanders darüber Buch führen, aber das ist ja noch umständlicher und demnach in keinster Weise sicherer. Und wie schon erwähnt, tut ja der zweite free nichts, wenn er über NULL ausgeführt wird.
Ein Bug ist das daher nicht einmal zwingend.
-
Auf der cert-Seite gibt es doch eine sehr aufschlussreiche Diskussion dazu, müssen wir das hier wiederholen?
-
hando schrieb:
Nur halt in diesem Empfehlungen von cert.org wurde der Cast auch für C empfohlen.
die erklärung mit dem widget/gadget ist doch doof. man kann den fehler auch so machen, dass es compiled aber trotzdem falsch ist.
-
Bashar schrieb:
Auf der cert-Seite gibt es doch eine sehr aufschlussreiche Diskussion dazu, müssen wir das hier wiederholen?
Nein natürlich nicht...kann von mir aus erstmal geschlossen werden.
Vielen Dank mal wieder