Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Dynamischer Array lässt sich nicht löschen!?
Pyromane - Mi 17.12.08 19:48
Titel: Dynamischer Array lässt sich nicht löschen!?
Ahoi,
ich habe hier ein Programm mit mehreren Formularen.
In einem dieser Formulare läuft ein Primzahlsieb...
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:
| ... TDynBoolArray=array of Boolean; ... implementation
procedure Sieb(max:integer); var i,k:integer; begin SetLength(feld,max-2); For i:=2 to max do feld[i-2]:=true; For i:=2 to round(sqrt(max)+1) do For k:=i to round(max/i) do feld[i*k]:=false; end;
procedure TForm_Sieb.Button1Click(Sender: TObject); var max,err,i:integer;
begin val(Sieb_ED_max.text,max,err); if err<>0 then ShowMessage('Fehlerhafte Eingabe!') else if max > 1 then begin Listbox1.Clear; Sieb(max); for i:=2 to max do if feld[i-2] then Listbox1.Items.Add(inttostr(i)); end else ShowMessage('Nur Zahlen größer 1 eingeben!'); end;
procedure TForm_Sieb.FormClose(Sender: TObject; var Action: TCloseAction); begin setlength(feld,0); end; |
das ist jetzt eine vereinfachte Version, eig. sollte die Sieb-Prozedur als Funktion in einer anderen Unit laufen und der Return-Array dann kopiert werden, doch da hat man nicht so gut durchgesehen ;)
-> Wenn ich das ausführe sürtzt das Programm immer mit einem InvalidPointer Error ab, egal wo ich das SetLength(Feld,0) setze
(also a) im Form_Sieb.Close, b) direkt nach dem schreiben, c) garnicht -> Dann wird es beim schließen der Mainform automatisch gemacht.)
sieht wer den Fehler?
MfG Pyromane
Moderiert von
Christian S.: Code- durch Delphi-Tags ersetzt
turboPASCAL - Mi 17.12.08 20:35
Und Feld ist wie deklariert ?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure Sieb(max:integer); var i,k:integer; begin SetLength(feld,max-2); For i:=2 to max do feld[i-2]:=true; For i:=2 to round(sqrt(max)+1) do For k:=i to round(max/i) do feld[i*k]:=false; end; |
Hier wird das Array ungeprüft verkleinert.
Xentar - Mi 17.12.08 20:36
Dein Array ist auch voll unterdimensioniert..
Edit: Ne, nicht unterdimensioniert - du rechnest nur komisch. Wieso i*k?
Angenommen, man hackt 9 als Wert ein.
Dann läuft die äußere for schleife (i, Zeile 11) bis Wurzel(9)+1 = 4
und die innere dann im schlimmsten Fall, also im ersten Durchgang bis round(9 / 2) = round(4,5) = 5
Du greifst also auf Speicherstelle 4*5 = 20 zu.. es gibt aber nur 7.. ups ;)
Dadurch überschreibst dir ganz toll irgendeinen Speicherbereich.
Für sowas gibts übrigens die Bereichsprüfung (Projektoptionen -> Debugger), sowie Haltepunkte..
Edit: Ahhhh, mein Fehler. Die Innere Schleife fängt ja bei K an, nicht bei 2. Verlesen :( Ok, dann ist mein Geschreibsel da oben hinfällig. Solltest trotzdem mal Zeile für Zeile durchgehen, und dir die Variablen anschauen.
Pyromane - Mi 17.12.08 23:17
OOps das deklarieren hab ich vergessen zu Posten:
var feld:TDynBoolArray;
steht über dem Implementation Bereich;
Und das mit dem Überschreiben sollte eig. nicht auftreten .. und wenn doch, was soll der Absturz beim Löschen denn mit dem Überschreiben irgendwelcher Variablen zu tun haben?
MfG Pyromane
Xentar - Mi 17.12.08 23:25
Nein, du musst das Array beim Beenden nicht auf 0 setzen.
Und hast du mal meinen Tipp mit der Bereichsprüfung ausprobiert? Dann sagt dir Delphi sogar, wo der Fehler auftritt..
- Bereichsprüfung rein -> Projekt neu erzeugen -> Starten
Pyromane - Do 18.12.08 00:08
Mhh also ich habs so gelernt ;) Unter; Guter Programmierstil *gg* und naja da es das Programm am Ende eh macht stürzt es ja trotzdem ab.
Bei der Prüfung bin ich grade dabei,,, wo zeigt es dann die Ergebnisse an?
So far Pyromane
Mhh hast recht es wird an einer Stelle überschritten... - Aber warum kommt an dieser Stelle kein Fehler? Achso mhh dyn. Arrays ich wusste da war was ;)Delphi geht mit denen ja sehr Stiefmütterlich um.
EDIT: Es wird sogar ziemlich Pöse überschritten ;)
jaenicke - Do 18.12.08 00:47
Die Prüfung solltest du übrigens wenn das Programm fertig ist wieder deaktivieren, die macht alle Zugriffe auf dynamische Arrays nämlich langsamer (weil jedesmal auch der Prüfcode ausgeführt wird).
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!