Array-Funktion zerstört Daten

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Nixsager
Beiträge: 168
Registriert: Sa 8. Okt 2016, 08:38
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Polska

Array-Funktion zerstört Daten

Beitrag von Nixsager »

Hi

Ich habe hier ein TP-Problem. Ich wollt es auch unter FP testen, aber wegen den ganzen genutzten Assembler-Befehlen war das nicht möglich.
Ich habe eine Funktion die Im Textmodus die Bilddaten ausliest und sie in einem Array ablegt.
Das Array habe mit folgendem in als Typ deklariert.

Code: Alles auswählen

 
Type
   ScreenAreaArray = Array[0..159, 0..24] of UInt8;
 


Ich habe in der Funktion, die die Funktion zum sichern der Bildschirmdaten aufruft eine Variabel als diesen Datentyp festgelegt.

Code: Alles auswählen

 
SA: ScreenAreaArray;
 


Die Bilddaten lese ich folgendermaßen aus.

Code: Alles auswählen

 
   For IndexY := 0 to (Height - 1) do
      For IndexX := 0 to (Width - 1) do
         begin
            CursorPositionSet(Page, X + IndexX, Y + IndexY);
            CharReadCurrent(Page, Char2Temp, ForegroundColor, BackgroundColor);
            ScreenArray[XTemp, IndexY] := Asc(Char2Temp);
            ScreenArray[XTemp+1, IndexY] := ForegroundColor + (BackgroundColor * 16);
            Inc(XTemp, 2);
         end;
 

Wenn ich diese Funktion aus einer anderen Funktion aufrufe, ändern sich Daten in der vorherigen Funktion.

Ich sehe absolut Grund, wieso dieser Fehler auftaucht.

Was mache ich falsch?

Gruß vom Nixsager

Nachtrag:
So wie ich jetzt heraus gefunden habe, scheint die Funktion zum zeichen der Daten auf dem Bildschirm dafür irgendwie mitverantwortlich zu sein.
In der Prozedur habe ich den Parameter der für den Array ist als Variabel deklariert.
Aber in der Prozedur lesen ich das Array nur aus.
Nehmen ich die Variabel-Deklaration weg, kriege ich Stack-Überlauf.

Hier der Code mit dem ich den Inhalt des Array auf dem Bildschirm zeichne.

Code: Alles auswählen

 
   For IndexY := 0 to (Height - 1) do
      For IndexX := 0 to (Width - 1) do
         begin
            CharTemp := ScreenArray[XTemp, IndexY];
            CharColorPaint(Chr(CharTemp), 1, Page, IndexX + X, IndexY + Y,
               (ScreenArray[XTemp+1, IndexY] DIV 16), (ScreenArray[XTemp+1, IndexY] MOD 16));
            Inc(XTemp, 2);
         end;
 
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!

Nixsager
Beiträge: 168
Registriert: Sa 8. Okt 2016, 08:38
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: Polska

Re: Array-Funktion zerstört Daten

Beitrag von Nixsager »

Hat eine eine Ahnung wie man dynamische Arrays machen könnte?
Jeder der sagt, ich könnte programmieren, der hat noch weniger Ahnung vom programmieren als ich!!!

Thandor
Beiträge: 153
Registriert: Sa 30. Jan 2010, 18:17
OS, Lazarus, FPC: Windows 10 64Bit/ lazarus 3.0 mit FPC 3.2.2 (32Bit + 64bit)
CPU-Target: 64Bit
Wohnort: Berlin

Re: Array-Funktion zerstört Daten

Beitrag von Thandor »

Anhand deiner Codeausschnitte kann ich leider keine Fehler erkennen, eventuell solltest du den Kompletten Code hier zeigen, oder als Datei anhängen.

In Turbo Pascal gab es, meines Wissens nach, keine dynamischen Arrays. Da wirst du wohl mit verkettete Listen arbeiten müssen.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Array-Funktion zerstört Daten

Beitrag von Socke »

Bitte poste doch ganze Funktionen; damit ist klar, wie dies Variablen definiert sind; z.B. schreibst du von einer Variablen SA, die (so habe ich geraten) mit dem Namen ScreenArray identisch sein könnte.

Code: Alles auswählen

 
   For IndexY := 0 to (Height - 1) do
      For IndexX := 0 to (Width - 1) do
         begin
            CursorPositionSet(Page, X + IndexX, Y + IndexY);
            CharReadCurrent(Page, Char2Temp, ForegroundColor, BackgroundColor);
            ScreenArray[XTemp, IndexY] := Asc(Char2Temp);
            ScreenArray[XTemp+1, IndexY] := ForegroundColor + (BackgroundColor * 16);
            Inc(XTemp, 2);
         end;
 

Du solltest sicherstellen, das Height und Width die Dimensionen des Arrays nicht überschreiten.
Die beiden Array-Dimensionen sollten ausschließlich aus den Zählvariablen IndexY und IndexX ableiten. Hier wird XTemp (was steht denn da drin?) als Array-Index verwendet, und in jeder X-Position um 2 erhöht. Damit erreichst du am Ende den Wert 160*25*2=8000 (angenommen XTemp ist beim Start der Schleifen gleich 0). Dieser Index ist in dem Array ScreenAreaArray weit außerhalb der Array-Grenzen, sodass du dir jede Menge Speicher überschreibst.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Mathias
Beiträge: 6194
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Array-Funktion zerstört Daten

Beitrag von Mathias »

In deinem Fall, wo es ein Abbild des VRAM darstellen soll, ist eine statische Array sowieso besser, vor allem wen sie 2D ist.

Somit kannst direkt auf jedes Zeichen im VRAM zugreifen.

Code: Alles auswählen

var
  ScreeBuffer : array[0..79, 0..24] of record
    ch : Char;
    col : Byte;
  end absolute $B800:$000;
 
begin
  ScreeBuffer[0,0].col := $04;
  ScreeBuffer[0,0].ch := #13;

Zeichnet eine roten Notenschlüssel links-oben.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten