Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » malloc/realloc

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
18.12.2004, 21:57 Uhr
Pablo
Supertux
(Operator)


Wenn ich sowas habe:


C++:
tmp = realloc(buffer, newlen);



und es gilt (nach Ausfürhung von realloc), dass tmp!=buffer, soll ich dann free(buffer) machen oder wird das automatisch gemacht? Angenommen es handelt sich um char*, hat dann tmp alle andere Elemente von buffer oder muss ich sie kopieren?
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
18.12.2004, 21:59 Uhr
Pablo
Supertux
(Operator)


Oh, ich glaube, ich hab schon aus den man pages:


Zitat:

If the area pointed to was moved, a free(ptr) is done.



also ein free(buffer) wird automatisch gemacht und ich muss nichts mehr kopieren, oder?
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
18.12.2004, 22:14 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


Also ich bin bisher immer davon ausgegangne das realloc sich um alles kümmert, auch wenn ich gerade nichts zum freigeben des evtl. alten Speichbereichs aus der MSDN rauslesen konnte.

Also das realloc die Daten kopiert wenn es den Speicherblock an der bestehen Stelle nnicht erweitern kann ist ja klar, dafür ist es ja da. Wenn ich mich aber jetzt noch selber vergleichen müsste ob der Speicher jetzt wo anders liegt und ich den alten freigeben muss, dann würde die Funktion in meinen Augen nicht sehr viel Sinn ergeben...


Außerdem wenns da steht wirds bestimmt so sein

Dieser Post wurde am 18.12.2004 um 22:14 Uhr von Guybrush Threepwood editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
19.12.2004, 11:24 Uhr
mike
Pinguinhüpfer
(Operator)


Aus Linux Unix Sys Programmierung (S. 142)

Zitat:

void *realloc(void *zeiger, size_t groesse);
verändert die Größe des Speicherbereichs, auf das "zeiger" zeigt, nach "groesse". Der Inhalt dieses neuen Objekts bleibt unverändert bis zur kleineren der alten oder neuen Größe. realloc(NULL, groesse) ist identisch zu malloc(groesse)


Kapitel 9.4 beschreibt die Funktionen dann auf 10 Seiten - das sollte mehr sein, als man über diese Funktion berichten kann

Achja, um überhaupt die ursprüngliche Frage zu beantworten: Freigeben must du nix. realloc macht alles selbst.

mfg
--

Dieser Post wurde am 19.12.2004 um 11:27 Uhr von mike editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
21.12.2004, 21:11 Uhr
Pler
Einer von Vielen
(Operator)


Meiner Meinung nach darf man das gar nicht machen.
Zuersteimal wird der alte Speicher ( falls nötig ) freigegeben.
Wenn man das selber noch mal machen will, wäre es ja schlecht, wenn sich die Bereiche überschneiden, und so würde man ja dann auch Speicher freigeben, den man eigentlich noch brauch( der dann zu dem neuen gehört ). Oder?

Bsp.:
Alte Länge ist 5
Alte Adresse ist 1000
Neue Länge ist 4
Neue Adresse ist 998

Dann würde ja free(1000) den Speicher von 1000 bis 1005 freigeben; 1000 bis 1002 gehören aber schon wieder zu dem Speicher hinter der Adresse 998!
Weis nicht ob das jetzt richtig ist, klingt doch aber ganz logisch.?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
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)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: