| Autor |
Beitrag |
Juniorsatan
      
Beiträge: 19
|
Verfasst: Mo 22.03.10 17:43
Ich probiere mich gerade an einer RLE-Kompression für dynamische Arrays.
Bisher funktionierte die Prozedur mit allen Testarrays, die ich manuell erstellt habe. Generiere ich jedoch ein größeres (wo bspw. die Farbwerte eines Bildes gespeichert sind), kommt es zu einem Stackoverflow.
Die sieht wie folgt aus:
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:
| procedure RLE(kanal_array: Array of Byte); var new_array: Array of Byte; k, count: integer; output:string; begin setlength(new_array, 0); k:=0; While ( k <= length(kanal_array)) DO Begin count:= countrep(kanal_array, k); if (kanal_array[k] = 255) then Begin setlength(new_array, (length(new_array) + 2)); new_array[(high(new_array)-1)]:= 255; new_array[(high(new_array))]:= 0; inc(k) End else if (count > 3) then Begin setlength(new_array, (length(new_array) + 3)); new_array[(high(new_array)-2)]:= 255; new_array[(high(new_array)-1)]:= count; new_array[(high(new_array))]:= kanal_array[k]; k:=(k + count); End Else Begin setlength(new_array, (length(new_array) + 1)); new_array[(high(new_array))]:= kanal_array[k]; inc (k); End; End; setlength(new_array, (length(new_array) - 1));
For k:=0 to high(new_array) DO begin output:= output + inttostr(new_array[k]) + '; '; end;
showmessage(output); end; |
Die Funktion countrep sucht redundante Einträge und sieht so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| function countrep(arr: Array of Byte; k:Integer): Integer; var n:integer; Begin n:=0; While ( ( (k+n) < high(arr) ) AND (arr[(k+n)] = arr[(k+n)+1]) AND (n < 253)) Do Begin inc(n); End; countrep:=n +1 ; End; |
Mich verwirrt wie gesagt der Fakt, dass es für kleine Arrays bisher tadellos funktionierte, Endlosschleifen o.ä. sehe ich auch nirgends. Habt ihr eine Idee?
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Mo 22.03.10 17:52
kann es sein das er sich in der markierten zeile aufhängt weil du mit <= length anstatt mit < length bzw <= high arbeitest?
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:
| procedure RLE(kanal_array: Array of Byte); var new_array: Array of Byte; k, count: integer; output:string; begin setlength(new_array, 0); k:=0; While ( k <= length(kanal_array)) DO Begin count:= countrep(kanal_array, k); if (kanal_array[k] = 255) then Begin setlength(new_array, (length(new_array) + 2)); new_array[(high(new_array)-1)]:= 255; new_array[(high(new_array))]:= 0; inc(k) End else if (count > 3) then Begin setlength(new_array, (length(new_array) + 3)); new_array[(high(new_array)-2)]:= 255; new_array[(high(new_array)-1)]:= count; new_array[(high(new_array))]:= kanal_array[k]; k:=(k + count); End Else Begin setlength(new_array, (length(new_array) + 1)); new_array[(high(new_array))]:= kanal_array[k]; inc (k); End; End; setlength(new_array, (length(new_array) - 1));
For k:=0 to high(new_array) DO begin output:= output + inttostr(new_array[k]) + '; '; end;
showmessage(output); end; |
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
Juniorsatan 
      
Beiträge: 19
|
Verfasst: Mo 22.03.10 18:09
Daran habe ich auch schon gedacht, deswegen prüfe ich in der darauffolgenden Funktion sofort, ob ich mich noch im Rahmen des Arrays bewege.
Delphi-Quelltext 1:
| While ( ( (k+n) < high(arr) ) AND ....) Do |
Mir wurde schulischerseits beigebracht, dass es bei solchen Prüfungen wichtig ist, dass diese "vorne" in der Bedingung stehen, sodass bei einem etwaigen Überschreiten die hinteren Expressions nicht mehr angesprochen wird, da es sofort zum Abbruch kommt.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 22.03.10 18:40
Dennoch läuft deine äußere Schleife in einen Fall rein, der ohne Behandlung un der inneren Schleife bleibt und damit nie verlassen wird. Schau Dir das doch einmal im Single-Step-Modus (F7/F  im Debugger an und beobachte die verschiedenen Werte.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Juniorsatan 
      
Beiträge: 19
|
Verfasst: Mo 22.03.10 18:43
Kann ich das in irgendeiner Weise zumindest ein wenig automatisieren? Das Array ist um die 4000000 Einheiten groß und ich kriege den Fehler bisher nicht anders reproduziert, als das ich das besagte Bild als Ausgangsmaterial verwende.
Nichtsdestotrotz werd ichs mir nochmal angucken.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mo 22.03.10 19:24
Haltepunkt setzen, links auf das rote Mumpel klicken --> Halötepunkt-Eigenschaften und da ne Bedingung eingeben.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
|