Autor Beitrag
Luzzifus
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 200

Win2K
D6 Prof
BeitragVerfasst: Mo 15.05.06 16:07 
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:
ausblenden 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..901..70of 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:
ausblenden 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:
ausblenden 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 - 39div 100) + 1;
  max := IDat[xt, yt].il + 1// zur Vereinfachung späterer Angaben.
  IDat[xt, yt].il := max;     // Die DB muss wissen dass wir's erhöht haben.
  SetLength(IDat[xt, yt].ItemData, max);
  with IDat[xt, yt].ItemData[max-1do 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:

ausblenden 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..10of Boolean;
  IDat                 : Array[1..901..70of TItemRec;


das hier:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var
  IDat                 : Array[1..901..70of TItemRec;
  picloaded            : Array[0..10of 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.
Luzzifus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 200

Win2K
D6 Prof
BeitragVerfasst: Mi 17.05.06 16:53 
Da ich dachte ich hätte beim Anpassen von DelphiX nen Fehler gemacht, hab ich mal auf UnDelphiX für Delphi6 geupgradet. Immer noch die gleichen Probleme. Hat das sonst echt niemand? Woran könnte es noch liegen?
Simon Joker
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 236
Erhaltene Danke: 1



BeitragVerfasst: Do 18.05.06 09:24 
Ich hatte mal ein ähnliches Problem -> www.delphi-forum.de/viewtopic.php?t=25462
Die Lösung war recht einfach aber nicht wirklich plausibel. Definiere mal alle array als Type, bevor du eine Variable erzeugst.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
    
type
  TItemData = Record
    x,y, art : Integer;
    map : Byte;
    empty : boolean;
  end;
  TItemDataArray = Array of TItemData;

  TItemRec = Record
    ItemData : TItemDataArray;
    il : Integer;
  end;
  TItemRecArray = Array[1..901..70of TItemRec;

var
  IDat : TItemRecArray;


Aber frage mich nicht, warum das dann funktioniert hat!

MfG Simon
Luzzifus Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 200

Win2K
D6 Prof
BeitragVerfasst: Sa 20.05.06 09:24 
Naja ich hab nun von mehreren Bekannten gehört dass sie ähnliche Probleme mit DelphiX haben und dass das wohl furchtbar verbuggt wäre. Fazit -> DelphiX Kompos rausgenommen und durch Graphics32 ersetzt (ich brauchte eh nur DirectDraw) und alles geht viel einfacher, schneller und vor allem ohne Access Violations.