Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Abbruch in Schleife mit Array (ungewollt)
Mrs. Sheep - Sa 04.04.09 08:31
Titel: Abbruch in Schleife mit Array (ungewollt)
Ich habe einen Array in den soll die ausführende Datei gespeichert werden (als Bytes).
Es ist in einer ganz normalen Konsolen-Anwendeung, und wenn ich die Schleife 9448 (genau 9448, jedes mal dasselbe) durchlaufen habe, hält das Programm an (wenn ich es aus Delphi per F9 starte endet es) und tut so als erwarte es Eingabe.
Hat irgendjemand irgendeine Idee?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| Pfad:=ParamStr(0); WriteLn(Pfad); CopyFile(PChar(Pfad), PChar(Pfad+'~'), False); i:=0; FileMode:=fmOpenRead; AssignFile(NäBrut, Pfad+'~'); Reset(NäBrut, 1); REPEAT i:=i+1; SetLength(Daten, i); BlockRead(NäBrut, Daten[i], 1); WriteLn(i,': ',Daten[i]); UNTIL EOF(NäBrut); Close(NäBrut); |
Edit: Inzwischen ist die Zahl der Schleifen minimal gestiegen.
Ich weiß nicht ob es bedeutsam ist, aber das Spielt sich alles auf einem USB-Stick ab. (Wo es eigentlich auch bleiben sollte)
Edite2: Habs jetzt doch mal auf die Main-HD gezogen, nichts verändert außer das es minimal weniger Schleifen sind.
Edite3: Der Taskmanager sagt:
Während des normalen Durchlaufens gehen beide CPU-Auslastungen hoch (auf ca 80%) (is'n Duo-CPU)
Wenn es stehen bleibt geht CPU1 in normal Betrieb (ca. 30%) und CPU2 sehr hoch (ca. 95 %)
Edite4: Ich bin frühstücken gegangen, hab meinen Stick mitgenommen, danach wieder angeschlossen und komm plötzlich bis 33004 was aber immer noch nich genug ist.
ReEdit4: Ich hab dann die neuste Version kompiliert; alles beim alten: 9448.
BenBE - Sa 04.04.09 13:06
Mrs. Sheep hat folgendes geschrieben : |
Hat irgendjemand irgendeine Idee?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| Pfad:=ParamStr(0); WriteLn(Pfad); CopyFile(PChar(Pfad), PChar(Pfad+'~'), False); i:=0; FileMode:=fmOpenRead; AssignFile(NäBrut, Pfad+'~'); Reset(NäBrut, 1); REPEAT i:=i+1; SetLength(Daten, i); BlockRead(NäBrut, Daten[i], 1); WriteLn(i,': ',Daten[i]); UNTIL EOF(NäBrut); Close(NäBrut); | |
Du hast einen Index-Fehler in deiner Schleife:
Delphi-Quelltext
1: 2: 3: 4:
| i:=i+1; SetLength(Daten, i); BlockRead(NäBrut, Daten[i-1], 1); WriteLn(i,': ',Daten[i-1]); |
Delete - Sa 04.04.09 13:06
Als aller erstes nimm mal den Umlaut aus dem Variablennamen.
Dann nimm eine while-Schleife:
Delphi-Quelltext
1:
| while not EOF(NäBrut) do |
Dann pack den Schleifenrumpf mal in einen try-except-Block. Eventuell kommt dann eine Fehlermeldung. Oder schlalte die Fehlerbehandlung mit
{$I-} aus und behandle die Fehler selber.
Dann erhöhe die Größe des Arrays nicht immer um eins. Denn dabei wird jedesmal das gesamte Array in einen neuen Speicherbereichkopiert und der alte wird von Delphi nicht gleich wieder freigegeben. Setz eine Anfangsgröße, die musst du schätzen und wenn das Array zu klein wird machst du es um 20 bis 30 Prozent größer. Am Schluss setzt du dann die tatsächlich gebrauchte Größe.
Mrs. Sheep - So 05.04.09 10:07
Vielen Dank, Luckie, ich hab das mit der WHILE-Schleife und der Erhöhung so geregelt und es lief ohne Probleme =)
Ob das mit der Fehlerbehandlung funktioniert hätte weiß ich nicht, da normalerweise sonst ja das Programm mit einem "[...] funktioniert nicht mehr." von Windows oder von Delphi beendet wird. Vielen Dank noch mal, Sheep.
JayEff - So 05.04.09 16:22
Mrs. Sheep hat folgendes geschrieben : |
| Vielen Dank, Luckie, ich hab das mit der WHILE-Schleife und der Erhöhung so geregelt und es lief ohne Probleme =) |
Nun, ich weiß jetzt nicht genau, ob "die Erhöhung *so*" bedeutet, dass du seine Methode oder deine Methode nutzt, auf jeden Fall solltest du Luckie's nutzen, da unter anderem der Algorithmus sehr langsam wird: Das andauernde umkopieren von einem ganzen Array nimmt sehr viel Zeit in Anspruch und (vorrübergehend) ein bisschen mehr RAM verwenden als eigentlich gebraucht wird, tut in den meisten Fällen nicht weh.
Mrs. Sheep hat folgendes geschrieben : |
| Ob das mit der Fehlerbehandlung funktioniert hätte weiß ich nicht, da normalerweise sonst ja das Programm mit einem "[...] funktioniert nicht mehr." von Windows oder von Delphi beendet wird. Vielen Dank noch mal, Sheep. |
Das "funktioniert nicht mehr" kommt von Windows und wird eigentlich nur dann ausgelöst, wenn das Programm längere Zeit nicht mehr auf Nachrichten reagiert, sprich, eingefroren ist. Das passiert unter anderem auch, wenn du eine Schleife hast, die ein paar Sekunden läuft, in der kein Application.ProcessMessages steht (Das soll jetzt nicht heißen, du sollst in jede Schleife möglichst 30-40 von diesen Zeilen einbauen :mrgreen: ). Mit Fehler meinte Luckie vermutlich in diesem Fall eine Exception (Darum redet er ja auch von einem try-except-block ), die in im Allgemeinen nicht zum Einfrieren eines Programmes führen. Ich vermute, Luckie meinte vorallem die E/A-Fehler die beim Lesen und Schreiben von Dateien auftreten können. Die Fehlernummern 100-106 stehen bei mir z.B. auch in der Delphi-Hilfe:
| Zitat: |
100 Fehler beim Lesen vom Datenträger - Wird von Read für eine typisierte Datei gemeldet, wenn Sie versuchen, über das Dateiende hinaus zu lesen.
101 Fehler beim Schreiben auf Datenträger - Wird von CloseFile, Write, WriteIn oder Flush gemeldet, wenn der Datenträger voll ist.
[...]
|
Delete - Mo 06.04.09 10:41
Jupp, so ist es. Ich glaube, nämlich dass sich Konsolenprogramme bei einer Exception einfach verabschieden ohne Fehlermeldung der aufgetretenen Exception. Bin mir aber nicht sicher.
Nersgatt - Mo 06.04.09 10:52
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| program Project1;
{$APPTYPE CONSOLE}
uses SysUtils;
begin WriteLn('Jetzt kommt eine Exception:'); WriteLn(FloatToStr(5/0)); end. |
Quelltext
1: 2: 3:
| C:\AGP\quellcodes\_testprojekt\Console Exception>project1 Jetzt kommt eine Exception: INF |
Hm, was will uns das "INF" sagen? :gruebel:
BenBE - Mo 06.04.09 10:57
INF = Infinity = Unendlich ;-)
@Luckie: Ja, tun sie, sei denn, man hat ein globales Try-Except. Ansonsten greift der Default-Handler von Windows, und der meldet diesen netten Dialog Windows ist abgestürzt, bzw. bei Konsolenprogrammen ein Terminate.
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!