![]() |
Stack Überlauf
Hallo,
ich habe folgendes Problem: Mein Programm enthält mehrere dynamische Arrays, denen ich mit setLength() eine Größe zuweise. Das klapt zunächst auch, aber sobalt ich versuche die Arraygröse im nachhinein mit dem selben Befehl zu verändern bekomme ich die Meldung Stack Überlauf. Die selbe Meldung bekomme ich wenn ich das Programm beende. Wenn ich die anderen Forumsbeiträge zum Thema Stack Überlauf richtig verstanden habe geht es bei der Meldung ja darum das ein Speicher voll ist, aber wie kann ein Speicher überlaufen wenn ich ein Array verkleinere oder das Programm beende? :gruebel: |
Re: Stack Überlauf
Hallo Leena,
willkommen im besten Delphi-Forum der Welt :-) Ein Stack-Überlauf deutet eigentlich auf einen rekursiven Aufruf, der nicht unterbrochen wird. procedure A; begin A; end; Ich denke nicht, dass Dein Problem durch SetLength direkt ausgelöst wird, sondern durch eine andere Funktion, die Du parallel ausführst (z.B. Freigeben von Objekten oder ähnlichem). Das würde auch dazu passen, dass das Problem auch beim Beenden des Programms auftritt... stahli |
Re: Stack Überlauf
Danke für den Hinweis.
Allerdings finde ich an der Stelle keine rekursive Prouedur.
Delphi-Quellcode:
Auserdem müste es, bei einer rekursiven entlosschleife doch schon deim ersten Programmdurchlauf zu einem Fehler kommen, oder?
procedure eingabe;
var i:integer; begin If zahler1 = 0 Then begin Form2.Label1.caption:=''; Form2.Label3.caption:=''; Form2.edit2.show; a:= strToInt(Form2.Edit1.Text); n:= 1; For i:=1 to a Do begin n:= n*a; end; setLength(El,a); setLength(Mo,n); setLength(Re,n,a); setLength(Vo,a); Form2.Edit1.Text:=''; end; end; |
Re: Stack Überlauf
Wo ist a deklariert?
edit: Und n? edit: vesprochen^^ |
Re: Stack Überlauf
Hallo Leena,
willkommen im Club der Delphianer :wink: Ist das beabsichtigt?
Delphi-Quellcode:
setlength hat hier drei Parameter?
setLength(Re,n,a);
@Frankfurtoder
Delphi-Quellcode:
a:= strToInt(Form2.Edit1.Text);
n:= 1; |
Re: Stack Überlauf
Aber muss nicht der Datentyp festgelegt werden von a sowie n? oder sind die variablen public/private?
|
Re: Stack Überlauf
@Frankfurtoder:
n und a, sind genau wie die Arrays und zahler1 als globale Variablen am Programm Anfang deklariert. @nahpets: Ja, die drei Parameter für setLength sind absicht da es sich um ein zweidimensionales Array handelt. |
Re: Stack Überlauf
Zitat:
Also wird das Problem weiter außen liegen. Von wo aus wird denn "Eingabe" überall aufgerufen? Auich beim Programmende? Das lässt der Prozedurname aber eher nicht vermuten... Setze doch mal einen Haltepunkt und schau Dir an, was vor und nach der Prozedur passiert... |
Re: Stack Überlauf
Hallo,
zeig' uns doch bitte mal den kompletten Quelltext. Wo wird eingabe aufgerufen, wie groß kann a sein? Tritt der Fehler unabhängig davon, ob a 1 oder 1000000 oder irgendwas anderes ist, auf? Von welchem Typ sind ElMoReVo? Auch bei relativ kleinem a kann die Größe der Arrays schon ziemlich "heftig" werden. Bei a = 2 hat Re 4*2 Elemente, bei a = 3 sind es 9*3, bei a = 10 sind's dann schon 10*10000000000, da könnte je nach Typ von Re der Speicher schon mal knapp werden. Selbst bei 'nem Byte pro Element hätte mein Rechner da schon lange Oberkante Unterlippe deutlich überschritten (hoffe, dass ich hier jetzt nicht vollständig falsch gerechnet habe). |
Re: Stack Überlauf
Ich weis, die Arrays sind ziemlich groß, aber bis jetzt habe ich nur die Werte 2, 3 und 4 für a ausprobiert. Der Fehler tritt immer auf.
Aufgerufen wird die "eingabe" nur in der Prozedur Edit1KeyDown:
Delphi-Quellcode:
Ein richtiges Programmende habe ich nicht programiert. Ich benutze einfach das Kreuz oben rechts um das Programm zu schliesen.
Me = Record
zeit: Integer; doppelt: boolean; end; Ar = Record zeit, t: Integer; end; var Form2: TForm2; El: Array of Ar; Mo: Array of Me; Re: Array of Array of Integer; Vo: Array of boolean; a,n,zahler1: Integer; procedure eingabe; begin {...} end; procedure berechne; begin {...} end; procedure TForm2.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin If Key =13 Then begin eingabe; If (zahler1 = a+2) Then berechne; zahler1:= zahler1+1; end; end; procedure TForm2.Button2Click(Sender: TObject); begin zahler1:=0; end; procedure TForm2.Form2Show(Sender: TObject); begin zahler1:= 0; end; end. |
Re: Stack Überlauf
Hallo,
habe mir mal den Quelltext genommen und das Ganze ausprobiert. Bei Eingaben > 8 kommt ein Fehler bei der Bereichsprüfung, ansonsten funktioniert der vorhandene Quelltext ohne Stacküberlauf oder sonstige Probleme. Ein Fehlerkandidat könnte dann nur noch die Prozedur Berechne sein. Was passiert darin? |
Re: Stack Überlauf
Dessenungeachtet ist es kein guter Stil, wenn ein Ereignis in einem Key-Down-Event aufgerufen wird. Abhilfe: Schmeiss ein TButton auf dein Formular, setze im Objektinspektor die Eigenschaft 'Default' auf TRUE (dann wird der Button beim ENTER gedrückt) und verfrachte zum Schluss die Logik in das ButtonClick-Ereignis.
Delphi-Quellcode:
Nur löst das ja nicht das Stack-Problem.
Procedure TForm1.Button1Click (Sender : TObject);
Begin eingabe; If (zahler1 = a+2)Then berechne; zahler1:= zahler1+1; End; |
Re: Stack Überlauf
Delphi-Quellcode:
Nach der Schleife entspricht n = a^a, was bei a=8 schon 2^24 = 16777216 entspricht. Vielleicht sollte man in diese Richtung mal weiter forschen.n:= 1; For i:=1 to a Do begin n:= n*a; end; setLength(El,a); setLength(Mo,n); setLength(Re,n,a); setLength(Vo,a); Bei Kombinatorik muss man etwas aufpassen was den benötigten Speicherplatz betrifft. |
Re: Stack Überlauf
Hallo,
a > 8 führt zwar zu Fehlern, aber nicht zum Stacküberlauf. Und bei a = 8 braucht's ja "nur" ca. 1 GB Speicher. |
Re: Stack Überlauf
Leena: Vielleicht kannst du mal die komplette Unit von TForm2 posten. Sieht aus, als kämen wir so nicht weiter.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:07 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz