Hallo allerseits,
ich arbeite zur Zeit an einem Projekt, in dem ich die DelphiX-Komponenten in ihrer aktuellsten Version mit Delphi 6 Professional benutze. Dazu habe ich unter Anleitung von offizieller Seite die Version für Delphi 5 selbst angepasst (gab nix anderes).
Nun komme ich dabei nicht um dynamische und nicht-dynamische Arrays herum und ich kriege auf einmal unerklärlichere Fehler ala Access Violations. Kleines Beispiel? Bittesehr:
Typen- und Variablendeklarationen, alles global:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| type TItemData = Record x,y, art : Integer; map : Byte; empty : boolean; end;
TItemRec = Record ItemData : Array of TItemData; il : Integer; end;
var IDat : Array[1..90, 1..70] of TItemRec; |
(Die Struktur soll als eine Art Gridfile dienen, also die Objekte mittels ihrer geometrischen Position (x,y) in eines der dynamischen Arrays von TItemRec einsortieren. Eine Art naive Hash-Funktion wenn man so will. Das nur zum Verständnis.)
Initialisierungen bei Form1.OnCreate:
Delphi-Quelltext
1: 2: 3: 4: 5:
| for i := 1 to 90 do for j := 1 to 70 do begin SetLength(IDat[i,j].ItemData, 0); IDat[i,j].il := 0; end; |
Einfügeoperation:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20:
| procedure TForm1.PMuClick(Sender: TObject); var xt, yt : Integer; max : Integer; begin DXTimer1.Enabled := false; xt := ((PopupMenu1.PopupPoint.X - xPosPic) div 100) + 1; yt := ((PopupMenu1.PopupPoint.Y - yPosPic - 39) div 100) + 1; max := IDat[xt, yt].il + 1; IDat[xt, yt].il := max; SetLength(IDat[xt, yt].ItemData, max); with IDat[xt, yt].ItemData[max-1] do begin x := PopupMenu1.PopupPoint.X - xPosPic; y := PopupMenu1.PopupPoint.Y - yPosPic - 39; map := ImageIdx; with Sender as TMenuItem do art := Tag; empty := false; end; DXTimer1.Enabled := true; end; |
Diese Prozedur gibt mir Access Violations bei (xt,yt)=(1,1) beim Hinzufügen und beim Beenden des Programmes (Runtime Error 216 = Access Violation). Der Runtime Error am Ende verschwindet, sobald ich die Deklaration von IDat entferne. Lustigerweise verschwinden alle auftretenden Access Violations (auch die am Ende), wenn ich die Deklaration von IDat vom Ende der global deklarierten Variablen an den Anfang verschiebe. Also statt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var xPosOld, yPosOld, xPPold, yPPold, xPosPic, yPosPic, max : Integer;
imgDrag, zoomed, bittewarten : Boolean;
ImageIdx : Byte; picloaded : Array[0..10] of Boolean; IDat : Array[1..90, 1..70] of TItemRec; |
das hier:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| var IDat : Array[1..90, 1..70] of TItemRec; picloaded : Array[0..10] of Boolean;
xPosOld, yPosOld, xPPold, yPPold, xPosPic, yPosPic, max : Integer;
imgDrag, zoomed, bittewarten : Boolean;
ImageIdx : Byte; |
Ich schwöre ich hab nix weiter geändert. Oo
Der aufmerksame Leser fragt sich jetzt vielleicht noch warum ich statt Length(Array) oder High(Array) die vergleichsweise umständliche Variante mit der Variable il benutze. Das hat den einfachen Grund dass ich in jeder Prozedur ausser der FormCreate-Prozedur die Länge auf die Art nicht korrekt auslesen kann. Da kommen dann irgendwelche lustigen Zahlen wie Length(IDat[xt,yt].ItemData) = 1200233455 raus (ja wirklich so groß), auch wenn ich vorher mit dem Array noch GAR NIX gemacht habe. Und das Resultat sind Access Violations ohne Ende.
Das alles ist mir noch NIE in einem anderen Projekt passiert und ich sehe auch keine logische Erklärung dafür. Deswegen schiebe ich das mal ganz dreist auf die DelphiX-Komponenten.
Falls jemand was sieht was ich nicht sehe bzw. näheres dazu weiß -> teach me.
so long,
luzzi.