realloc - fehlerhafter Wert im Array
-
ralloc benutzt du falsch.
else { new_space = realloc(stck->arrStack, stck->size+50*sizeof *stck->arrStack); if(new_space == NULL) return 0; /* das kopieren kannst du dir schenken, das garantiert realloc bereits */ stck->arrStack = new_space; //Größe anpassen stck->size+=50; //neuen Wert speichern stck->arrStack[stck->top+1] = val; stck->top++; }
-
Außerdem
stck->arrStack[stck->top+1] = val;
sieht mir irgendwie verdächtig aus. Ich habe es nicht getestet, aber müsste es nicht
stck->arrStack[stck->top] = val;
heißen?
-
Vielen Dank erstmal für die zügigen Antworten.
Durch die Änderung:
new_space = (int *)realloc(stck->arrStack , stck->size+50 * sizeof *stck->arrStack);
Kommt das gleiche Ergebnis heraus.
Durch entfernen der +1 bei :
stck->arrStack[stck->top] = val;
Die +1 müsste doch richtig sein oder? weil bei top der letzte Wert drin steht.
kommt:
9 8 7 6 -842... 5 3 2 1 0Muss ich überhaupt den temporären Zeigen new_space verwenden..?
-
Ich würde dir raten die Anweisungen für das hinzufügen des Werten aus der Abfrage raus zu nehmen. Du machst dort zweimal das gleiche, es könnte also sein, dass du dort nicht das +1 geändert hast.
-
int stck_push(struct stack *stck, int val) { if(!(stck->top < stck->size)) { //Stack muss erweitert werden um 50 Elemente stck->arrStack = (int *)realloc(stck->arrStack , stck->size+50 * sizeof(int)); if(stck->arrStack == NULL) return 0; //Größe anpassen stck->size+=50; } //neuen Wert speichern stck->arrStack[stck->top] = val; stck->top++; return 1; } int stck_pop(struct stack *stck, int *val) { if(!stck) return 0; if(stck->top > 0) { stck->top--; *val = (int)stck->arrStack[stck->top]; } else return 0; return 1; }
Ich habe den push-befehl eingekürzt. Das Problem lag daran top mit 0 initialisiert wird.Dann aber gleich beim ersten Durchgang 1 gesetzt wird. Damit gab es eine Verschiebung. Zusätzlich war im pop-Befehl top-- an einer falschen Stelle (nach *val=(int)stck...).
Jetzt geht es.
Vielen Dank!
-
Es ist übrigens üblich im Erfolgsfall eine 0 zurück zugeben und sonst den konkreten Fehler. Das macht die Fehlersuche einfacher.
#define NO_STACK 1 #define REALLOC_FAILED 2 ...
-
Du treibst dennoch ein gefährliches Spiel. realloc kann auch 0 zurückliefern, der Speicherbereich wird dann nicht freigegeben. Da du die alte Adresse überschreibst, kannst du mit ihm aber nichts mehr anfangen -> Inhalt verloren & Speicherleck entstanden.
-
Ich teste doch auf NULL. Damit bekomme ich doch mit wenn es nicht geklappt oder?
manual:
"If there is not enough available memory to expand the block to the given size, the original block is left unchanged, and NULL is returned.
If size is zero, then the block pointed to by memblock is freed; the return value is NULL, and memblock is left pointing at a freed block."Danke für den Tipp. Die defines habe ich in meinem Headerfile deklariert. Wie mach ich das wenn ich viele Funktionen habe mit einem zugehörigen Headerfile. Dann müsste ich ja die defines durchnummeriern..
Müsste ich dann pro Funktion ein enum anlegen mit den Funktionszugehörigen Fehlercodes?Oder wie macht man das richtig?
-
Richtig oder falsch kommt wohl immer auf das konkrete Problem an. Da die Funktionen aber alle auf das Stack-Objekt operieren, würde ich eine Liste mit möglichen Fehlern auf eben dieses Objekt anlegen. Eigene Fehlercodes pro Funktion halte ich sogar für eher ungünstig, so muss der Programmierer immer schauen, was bedeutet denn dieser Fehler an der Stelle. Auch geht dadurch die Bedeutung des Fehlers, wenn du ihn nach oben hin durch reichst verloren. Außer du bastelst eine Kennung mit rein, anhand derer man erkennen kann, wer den Fehler verursacht hat.
-
snowy schrieb:
Ich teste doch auf NULL. Damit bekomme ich doch mit wenn es nicht geklappt oder?
Das Problem ist, dass du stck->arrStack vor dem Vergleich schon NULL gesetzt hast.
Damit ist die Adresse des Speicherblocks weg und du kannst, wie schon gesagt, kein free() mehr aufrufen.
Was du brauchst ist ein:stack *temp = realloc... if(temp == NULL) //fehler else stck->arrStack = temp;