Schleifen - malloc & free
-
Hi, habe ein Problem mit der Speicherverwaltung eines meiner Programme.
Ich glaube aber auch schon den Fehler gefunden zu haben, und zwar habe ich folgende Schleife in meinem Programm:for(k=wert;k>i;k--) { Array[k] =(char *)malloc(strlen(Array[k-1])); // Speicher wird reserviert memset(Array[k],0,strlen(Array[k-1])); // String wird mit ' ' vorbelegt strcpy(Array[k],Array[k-1]); // alle nach k folgende Felder werden ein Feld nach hinten kopiert }
dieses Array wird also von hinten beginnend bearbeitet, und es wird auch jedes mal speicherplatz angefordert (malloc)bis hin zum 1. element der schleife. Leider wird das immer mehr und irgendwann stürzt das programm ab. Wie kann ich in die schleife noch ein free einbauen, das wenn die schleife durchlaufen ist das letzte element, das nicht mehr verwendet wird, wieder freizugeben???
-
Das Programm stürzt wohl eher deswegen ab, weil du vergessen hast auch für das Stringendezeichen Speicherplatz zu reservieren
-
ich habe vorher aber irgendwo zu stehen:
Array[wert] = (char *)malloc(STR_MAX+1); memset(Array[wert],0,STR_MAX+1);
reicht das nicht aus? muss ich in die schleife kein free rein bringen? wie kann ich denn sonst für das stringendezeichen speicherplatz reservieren?
-
Was hast du nun in der Schleife stehen?
Das?
evil411 schrieb:
... Array[k] =(char *)malloc(strlen(Array[k-1])); // Speicher wird reserviert memset(Array[k],0,strlen(Array[k-1])); // String wird mit ' ' vorbelegt ...
Oder das?
evil411 schrieb:
Array[wert] = (char *)malloc(STR_MAX+1); memset(Array[wert],0,STR_MAX+1);
-
AJ schrieb:
Was hast du nun in der Schleife stehen?
... das habe ich in der schleife zu stehen:
Array[k] =(char *)malloc(strlen(Array[k-1])); // Speicher wird reserviert memset(Array[k],0,strlen(Array[k-1])); // String wird mit ' ' vorbelegt
und das...
Array[wert] = (char *)malloc(STR_MAX+1); memset(Array[wert],0,STR_MAX+1);
... habe ich schon weiter oben zu stehen (d.h. nicht in der Schleife)
-
Warum reservierst du vorher schon Speicher, wenn du den Speicher eh nochmal in der Schleife neu reservierst???
Ich seh nur den Fehler, dass du in der Schleife zu wenig Speicher reservierst. Denn Sinn von free() sehe ich auch nicht nach der Schleife. Schließlich schaut das eher so aus, als hättest du ein weiteres Element angehängt und nicht gelöscht. Du müsstest eher ein free() in der Schleife machen oder eigentlich noch besser, sollte da ein realloc() sein, dann würde das malloc() vor der Schleife auch wieder Sinn machen.
Kannst du mal erklären was du überhaupt mit dem ganzen bezwecken willst?
-
ja...
wie gesagt, ich hatte gestern in einem thread geschrieben, dass ich ein bereits getestetes programm (auf schnellem Rechner), auf einem sehr langsamen rechner mit geringem arbeitsspeicher getestet habe. Auf dem schnellen pc läuft das programm problemlos, auf dem langsamen pc läuft es nicht, weil der zugesicherte speicher (in Taskmanager erkennbar)seinen maximalen grenzwert erreicht. In dem thread wurde mir dann als tipp mit auf den weg gegeben, dass es sicherlich daran liegt, dass evtl. irgendwo ein malloc ist, wo kein free ist. und da ist mir diese schleife aufgefallen.
diese schleife sollte eigentlich alle nachfolgenden felder (nach k) um eins nach hinten kopieren. Muss aber irgendwie wieder speicher freigeben?!?
Wenn ich die ganze sache beim ausführen beobachte, dann steigt der zugesicherte speicher bis er den grenzwert erreicht hat und dann ist sense.
die komplette schleife sieht so aus:int i=0; //steht noch ganz oben if( (start) && (strlen(Array[i])<1) ) { Array[Wert] = (char *)malloc(STR_MAX+1); // Speicher wird reserviert memset(Array[wert],0,STR_MAX+1); // String wird mit ' ' vorbelegt for(k=wert;k>i;k--) { Array[k] =(char *)malloc(strlen(Array[k-1])); // Speicher wird reserviert memset(Array[k],0,strlen(Array[k-1])); // String wird mit ' ' vorbelegt strcpy(Array[k],Array[k-1]); // alle nach k folgende Felder werden ein Feld nach hinten kopiert } wert++; }else start= 0;
}
-
evil411 schrieb:
int i=0; //steht noch ganz oben if( (start) && (strlen(Array[i])<1) ) { //Wert groß? ist das absicht? Array[Wert] = (char *)malloc(STR_MAX+1); // Speicher wird reserviert memset(Array[wert],0,STR_MAX+1); // String wird mit ' ' vorbelegt for(k=wert;k>i;k--) { //k==wert, und Array[wert] wurde schon allokiert -> mem leak //hat Array[k-1] denn wirklich einen 'wert'? wurde es allokiert und ein string //samt terminierender 0 reingeschrieben? //man beachte, dass das +1 fehlt!! Array[k] =(char *)malloc(strlen(Array[k-1])); // Speicher wird reserviert memset(Array[k],0,strlen(Array[k-1])); // String wird mit ' ' vorbelegt //nicht genug speicher -> PENG strcpy(Array[k],Array[k-1]); // alle nach k folgende Felder werden ein Feld nach hinten kopiert } wert++; }else start= 0;
}
-
Shade Of Mine schrieb:
//Wert groß? ist das absicht? Array[Wert] = (char *)malloc(STR_MAX+1); // Speicher wird reserviert //*****Keine Absicht... sorry, habe es eigentlich auch klein***** memset(Array[wert],0,STR_MAX+1); // String wird mit ' ' vorbelegt for(k=wert;k>i;k--) { //k==wert, und Array[wert] wurde schon allokiert -> mem leak //*****was kann ich dagegen tun?***** //hat Array[k-1] denn wirklich einen 'wert'? wurde es allokiert und ein string //samt terminierender 0 reingeschrieben? //man beachte, dass das +1 fehlt!! //*****ja, hat einen wert, allokiert glaube ich noch nicht***** Array[k] =(char *)malloc(strlen(Array[k-1])); // Speicher wird reserviert memset(Array[k],0,strlen(Array[k-1])); // String wird mit ' ' vorbelegt //nicht genug speicher -> PENG //*****WARUM?***** strcpy(Array[k],Array[k-1]); // alle nach k folgende Felder werden ein Feld nach hinten kopiert } wert++; }else start= 0;
}
Was kann ich tun? Wie kann ichs ändern?
-
warum habe ich bei dem 2. malloc keinen speicher mehr und warum macht es peng? wie kann ich denn das ändern?
-
Wie schon gesagt, entweder machst du in der Schleife anstatt dem malloc() ein realloc() oder du machst vor dem malloc() noch ein free().
Es macht deswegen PENG, weil der Speicher, den du vor der Schleife bereits reservierst nicht freigegeben wird, d. h. bei jedem Durchlauf deiner Schleife bleiben Speicherleichen zurück und zwar genau in der Anzahl an Elementen deines Arrays. Kein Wunder, dass dein Speicher über kurz oder lang voll läuft.
-
und wie würde das genau aussehen? jedesmal wenn ich dort ein free reinbringe bekomme ich immer die fehlermeldung: debug assertion failed... Expression: _CrtIsValidHeapPointerPUserData
oder wie würde das denn mit realloc genau aussehen? das benötigt doch zwei parameter oder?
-
evil411_unlogged schrieb:
und wie würde das genau aussehen? jedesmal wenn ich dort ein free reinbringe bekomme ich immer die fehlermeldung: debug assertion failed... Expression: _CrtIsValidHeapPointerPUserData
Dann hat der Zeiger auf den du free() machst keinen ordentlich allokierten Speicher.
Dann hilft auch realloc() nix
-
diese meldung erscheint aber nicht immer... je nachdem wo ich mein free hinschreibe. Kann auch sein, dass ich ein falsches free hinschreibe. Wie müsste es denn wo stehen?
ich habe es jetzt hier zu stehen:if( (start) && (strlen(Array[i])<1) ) { Array[Wert] = (char *)malloc(STR_MAX+1); // Speicher wird reserviert memset(Array[wert],0,STR_MAX+1); // String wird mit ' ' vorbelegt for(k=wert;k>i;k--) { free(StrMemo[k-1]); Array[k] =(char *)malloc(strlen(Array[k-1])); // Speicher wird reserviert memset(Array[k],0,strlen(Array[k-1])); // String wird mit ' ' vorbelegt strcpy(Array[k],Array[k-1]); // alle nach k folgende Felder werden ein Feld nach hinten kopiert } wert++; }else ...
Stimmt denn das?
Da kommt nämlich die Meldung: blocktype is valid(pHead->nBlockUse)
-
...natürlich stegt anstatt StrMemo --> Array
-
kann mir nicht zufällig jemand ne Lösung für diese Schleife präsentieren wie er es machen würde? so langsam sehe ich vor lauter frees und mallocs gar nicht mehr durch. bekomme eine fehlermeldung nach der anderen. Am besten mit einem realloc IN der Schleife...
-
for(k=wert;k>i;k--) { Array[k] =(char *)realloc(Array[k], strlen(Array[k-1])+1); // Speicher wird reserviert memset(Array[k],0,strlen(Array[k-1])); // String wird mit ' ' vorbelegt --> ist eigentlich überflüssig strcpy(Array[k],Array[k-1]); // alle nach k folgende Felder werden ein Feld nach hinten kopiert }
Das ist alles.
Spätestens beim Programmende solltest du natürlich für alle dynamisch reservierten Elemente ein free() machen. Wo du den Speicher wieder freigeben musst, hängt davon ab, wo du Array deklariert hast. Wenn du Array als lokale Variable in einer Funktion z. B. deklarierst hast, dann musst du den reservierten Speicher am Ende der Funktion wieder freigeben!
for(k=0;k<anzelemente;++k) { free(Array[k]); }
anzelemente = Die Anzahl der Elemente des Arrays Array