Zitat:
PS: Der Fehler von heute morgen tritt nun nicht mehr auf (kein Absturz beim Einlesen von Blöcken)
Wie ist das möglich ? Der Code steckt nämlich voller Fehler. Oder sind die inzwischen beseitigt ?:
Zunächst einmal: Vermutlich hast Du in den Compileroptionen die Bereichsüberprüfung sowie die Überlaufprüfung abgeschaltet. Das aber sollte man während der Entwicklung nie machen. So siehst Du natürlich nicht, wo eklatante Fehler im Programm stecken und wann genau sie auftreten.
In der Methode THuffman.KodiereArray() heißt es:
Code:
for i := High(sOutput) - 2 downto 0 do
sOutput[i + 3] := sOutput[i];
Du gibst also als oberen Grenzwert der Schleifenvariable 2 Positionen vor der oberen Grenze des Arrays an ("High(sOutput) - 2"), willst dann aber innerhalb dieer Schleife eine (nicht existente) Position des Arrays belegen ("sOutput[i + 3]") ! Im Klartext eines simplen virtuellen Beispiels: High(sArray) sei 100, i wird der maximale Wert i= High(sArray)-2 = 100-2 = 98 zugewiesen, aber dann auf die Position [i+3] = [101] des Arrays zugegriffen, was zwangsläufig in die Hose geht.
In der Methode THuffman.Dekodieren(): die Variable iPos ist genau wie die Felder iLinks und iRechts des Records Baum als Integer deklariert, alle können also im Laufe der Abarbeitung durchaus einen Wert >255 enthalten. Der Wert von iPos (geholt aus den Feldern des Records) wird aber übergeben an eine Instanz von TAusgabe, welche jedoch ein Array von Byte ist. Folglich (und beobachteterweise auch tatsächlich) kommt es im Verlauf irgendwann zu der dadurch provozierten Inkompatibilität, d.h. zum Bereichsüberlauf..
Im übrigen:
Sämtliche Konstruktoren der Objekte sind im nachfolgenden nicht durch Try..Finally Blöcke gesichert, so dass im Falle eines Crashs (wie er beim derzeitigen Stand der Programmierung an verschiedenen Stellen ausgelöst wird) nicht zu einer Freigabe der von den Objekten belegten Speicherbereiche kommt. Die Folgen dürften ja bekannt sein.
Es gibt ebenso nicht einen einzigen Versuch, evt. Fehler in kritischen Passagen durch
Exception-Blöcke abzufangen und dadurch genauer zu lokalisieren.
Wenig professionel ist auch die ständige Längenveränderung der dynamischen Arrays innerhalb der zahlreichen Schleifen: teilweise nehmen die Schleifenzähler enorm hohe Werte an, und bei jedem Durchgang muss das komplette betroffene Array wegen seiner Verlängerung (um gerade mal 1) immer wieder neu im Speicher umkopiert werden. Die Möglichkeit, dass sich der Rechner bei dieser extrem aufwändigen und gleichzeitig extrem schnellen Veränderung in der Verwaltung des Heaps schon mal verhaspeln könnte, ist vielleicht nicht ganz abwegig (nobody is perfect).
Es mag im Code durchaus noch weitere Stellen geben, wo derart Unzulässiges oder Fragwürdiges passiert. Ich habe die Analyse wegen der vielen Unzulänglichkeiten irgendwann aufgegeben.