005
22.12.2004, 09:20 Uhr
virtual
Sexiest Bit alive (Operator)
|
Also der alte Speicher wird schon freigegeben. Also folgender Code ist gültig und macht kein Speicherloch:
C++: |
int main() { char* buffer = malloc(10); char* buffer2 = realloc(buffer, 20); ... free(buffer2); }
|
Auf die eigentlich notwendige Fehlerbehandlung hab eich hier jetzt mal verzichtet.
Ein recht verbreiteter Fehler ist jedoch folgendes (hier mal mit Fehlerbehandlung, anhand eines denkbar realen Beispiels):
C++: |
/* Struktur für ein dyn. char array */ typedef struct { char* ptr; size_t capacity; size_t size; } char_array_t;
// Funktion: Verändern der Capacity int chg_capacity(char_array_t* ca, size_t new_capacity) { ca->ptr = realloc(ca->ptr, new_capacity); if (!ca->ptr) return -1; ca->capacity = new_capacity; return 0; }
|
chg_capacity dient dazu, die Kapazität des Chararrays zu verändern und gibt 0 im Erfolgsfall, -1 im Fehlerfall zurück. Wir haben hier zwar eine Korrekte Fehlerbehandlung eingebaut, aber nichtsdestotrotz realloc falsch angewendet. Schlägt realloc nämlich fehl, bleibt der ursprüngliche Speicher unverändert. Geht realloc gut, wird der alte Speicher freigegeben. In obigen Beispiel wird im Fehlerfall jedoch das ca->ptr mit einem NULL Pointer überschrieben und wird haben damit keinen Zugriff mehr auf den alten, noch gültigen Speicher und damit - neben einem invaliden char_array_t - ein Speicherloch. Daher: den Rückgabewert von realloc immer in einer lokalen variable zwischenspeichern und testen:
C++: |
// Funktion: Verändern der Capacity int chg_capacity(char_array_t* ca, size_t new_capacity) { char* temp = realloc(ca->ptr, new_capacity); if (!temp) return -1; ca->capacity = new_capacity; ca->ptr = temp; return 0; }
|
-- Gruß, virtual Quote of the Month Ich eß' nur was ein Gesicht hat (Creme 21) |