Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Stack Überlauf - Beim sprung in eine Schleife
gispos - Mo 24.11.08 20:12
Titel: Stack Überlauf - Beim sprung in eine Schleife
Hallo zusammen,
ich habe da ein Problem mit Befehlen die aus einem Loop heraus ausgeführt werden.
Unterer Code ist nur ein kleines Beispiel, dass so aber in meinem richtigen Code auftreten kann. Es wird aus dem Loop heraus in eine andere Procedure gesprungen hier (Check), dort wird ein Wert geprüft und bei Erfolg sofort der Loop mit nächstem Index weiter ausgeführt, was dann aber bei ca. 100000 Durchläufen zu einem Stack Überlauf führt.
Einzige Möglichkeit um dies zu vermeiden ist das RunLoop über PostMessage zu senden (Check_Post), was aber den Nachteil des langsamen ausführen mit sich bringt und dadurch falsche Ergebnisse liefern kann.
Entweder sehe ich vor lauter Bäumen den Wald nicht, oder… meine Kenntnisse reichen nicht aus. :(
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59:
| const WM_RUNLOOP = WM_USER + 99;
procedure TForm1.OnAppMessage(var Msg : tagMSG; var Handled : Boolean); begin If Msg.message = WM_RUNLOOP then begin Handled:= True; RunLoop(Msg.WParam); end else Handled := False; end;
procedure Check_Post; begin PostMessage(Application.Handle, WM_RUNLOOP, CurrLoop + 1, 0); end;
procedure Check; begin Form1.RunLoop(CurrLoop + 1); end;
procedure TForm1.RunLoop(Index: Integer); begin While Index < 100000 do begin CurrLoop := Index; inc(Index); Application.ProcessMessages;
Check;
exit; end; end;
procedure TForm1.Button1Click(Sender: TObject); begin Application.OnMessage := OnAppMessage; Caption := 'Start'; RunLoop(0); Caption := 'Fin'; end; |
Vielleicht sollte ich alle Proceduren in die Procedure RunLoop mit einbinden, so das bei Erfolg nicht in den Loop gesprungen wird. Sind aber ca. 50 Proceduren und da müsste ich dann einiges Umschreiben.
Kann mir da jemand weiterhelfen?
Gruß gispos
JayEff - Mo 24.11.08 20:49
Klingt für mich nach endloser doppelter Rekursion: Prozedur A ruft B auf, die ruft A auf, die ruft B auf, die ruft A auf ... und in null komma nix ist der Aufrufestack voll. Du musst bedenken, wenn A B aufgerufen hat, ist A immernoch auf dem Stack. dann ruft B A auf, und dann sieht der stack so aus: A-B-A. und es geht weiter, denn A ruft ja wieder B auf: A-B-A-B-A-B... Das ist etwas, auf das man bei Rekursion achten muss.
gispos - Mo 24.11.08 21:21
JayEff mal danke für deine Antwort… hilft mir nur leider nicht weiter.
Ja der Stack häuft die einzelnen Aufrufe an und ist irgendwann voll weil die Schleife noch nicht beendet war und wieder in die Schleife gesprungen wird.
Wie kann ich dies aber am besten vermeiden ohne mein RunLoop zum Stillstand zu bringen?
Hat sich erledigt. :D
Muss eben alle Proceduren in Functionen umschreiben.
Wenn True zurück geliefert wird läuft die Schleife einfach weiter.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| Function Check : boolean; Begin If Wert then Result := True else begin Result := False; WaitThread := TWaitThread.Create(Wert); end; End;
Procedure RunLoop(Index : Integer); Begin While Index < 100000 do Begin CurrLoop := Index; Inc(Index); Application.ProzessMessages; If not Check then exit; End; |
Gruß gispos
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!