Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Porblem mit Arrays, die Pointer auf Record sind (https://www.delphipraxis.net/89269-porblem-mit-arrays-die-pointer-auf-record-sind.html)

darthdungeon 28. Mär 2007 19:22


Porblem mit Arrays, die Pointer auf Record sind
 
Hallo Com,

mein ersten thread hier im forum ;P

also, mein problem. ich habe 3 types definiert, die records sind:

Delphi-Quellcode:
type TPoints = record
  x, y : Integer;
end;

type
  TEdge =^PEdge;
  PEdge = record
  point1, point2: TPoints;
  next_edge: TEdge;
end;

type TArea = record
  edge: TEdge;
end;
nun habe ich noch 3 arrays:
Delphi-Quellcode:
 
area_list: array of TArea;
edge_list: array of TEdge;
point_list: array of TPoints;
hintergrund: ich habe 2-dimensionale polygone, die ich mit hilfe der datenstruktur beschreiben will. ein punkt vom typ tpoints besteht logischerweiße aus 2 koordinaten, eine kante vom typ tedge hat einen end- und einen anfangspunkt vom typ tpoint und die information darüber welche kante an ihrem ende liegt. damit kann ich eine fläche dadurch eindeutig beschreiben, das ich nur eine kante dafür angeben brauche,um nicht daten doppelt speichern zu müssen.
nun speicher ich alle punkte in das array point_list, das is kein problem.
wenn ich jetzt aber ein rechteck beschreiben möchte, speicher ich in point_list 4 punkte ab. dann weise ich edge_list[0] den 2 punkten aus point_list zu und zeige dann mit next_edge auf next_edge[1]. so viel zur theorie. das zuweisen mit werten an sich funktioniert, nur muss ich ja in den reocrds zeiger auf die punkte in ponit_list haben will, damit ich nicht ein punkt tausendmal ändern muss, sondern nur einmal in point_llist.
wie kann ich also die pointer richtig deklarieren?

Delphi-Quellcode:
setlength(area_list, 1);
setlength(edge_list, 4);
setlength(point_list, 4);


point_list[0].x:=100;
point_list[0].y:=100;

point_list[1].x:=500;
point_list[1].y:=100;

point_list[2].x:=500;
point_list[2].y:=500;

point_list[3].x:=100;
point_list[3].y:=500;

edge_list[0].point1:=point_list[0];
edge_list[0].point2:=point_list[1];
edge_list[0].next_edge:=edge_list[1];
edge_list[1].point1:=point_list[1];
edge_list[1].point2:=point_list[2];
edge_list[1].next_edge:=edge_list[2];
edge_list[2].point1:=point_list[2];
edge_list[2].point2:=point_list[3];
edge_list[2].next_edge:=edge_list[3];
edge_list[3].point1:=point_list[3];
edge_list[3].point2:=point_list[0];
edge_list[3].next_edge:=edge_list[0];

area_list[1].edge:=edge_list[1];
quasi das, nur das ich nicht der linken seite einmalich die rechteseite zuordnet, sondern eine pointer drauf setzte? :?:

pszopp 28. Mär 2007 20:10

Re: Porblem mit Arrays, die Pointer auf Record sind
 
Hallo darthdungeon und willkommen in der DP!

Ich weiß leider nicht genau wie du es lösen willst. Ich habe hier mal einen Ansatz für dich.

Der Type- und Var-Abschnitt sieht meiner Meinung nach so aus:
Delphi-Quellcode:
type
  // TPoint existiert bereits in der Unit Types, kann also weggelassen werden falls, du
  // aus TPoints TPoint machst!
 
  // Einen Zeiger auf einen TPoint definieren.
  PPoint = ^TPoint;


  // Zeiger auf eine Kante.
  PEdge = ^TEdge;
  // Kante definieren.
  TEdge = record
    point1, point2: PPoint; // Und hier den Zeiger benutzen.
    next_edge: PEdge;
  end; // TEdge

  TArea = record
    edge: TEdge;
  end; // TArea

...

var
  area_list: array of TArea;
  edge_list: array of TEdge;
  point_list: array of TPoint;

Die Implementierung wird dann wie folgt angepasst:
Delphi-Quellcode:
// Bleibt wie gehabt.
point_list[0].x := 100;
point_list[0].y := 100;
...

// Hier muss man Delphi nun sagen, dass man einen Zeiger auf einen TPoint hat.
edge_list[0].point1 := @point_list[0];
edge_list[0].point2 := @point_list[1];
...

// So wird der Zeiger initialisiert.
edge_list[0].next_edge := @edge_list[1];


// Zum Zugriff auf die Zeiger musst du dann später so vorgehen.
ShowMessage( IntToStr( edge_list[0].point1^.x ));
ShowMessage( IntToStr( edge_list[0].next_edge^.point1^.x ));
Achtung: Ich hab das leider nicht getestet!

Gruß,
pszopp

darthdungeon 28. Mär 2007 20:23

Re: Porblem mit Arrays, die Pointer auf Record sind
 
danke für die schnelle antwort, werde das mal testen und das ergebnis hier posten. trotzdem, schonmal vielen danke :wink:

darthdungeon 29. Mär 2007 19:22

Re: Porblem mit Arrays, die Pointer auf Record sind
 
okay, danke funktioniert wirklich.^^
nur wenn ich das prog schließe, kriege ich EAccessViolation-Errors, ne unschöne sache. wieso und wie bekomme ich die weg?
mein bisheriger programmcode:

Delphi-Quellcode:
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;
type
  PPoints = ^TPoints;

  TPoints = record
   x, y : Integer;
   end;

  PEdge = ^TEdge;

  TEdge = record
  point1, point2: PPoints;
  next_edge: PEdge;
  end;

  TArea = record
  edge: TEdge;

end;

type
  TForm1 = class(TForm)
    Image1: TImage;
    procedure FormCreate(Sender: TObject);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    area_list: array of TArea;
    edge_list: array of TEdge;
    point_list: array of TPoints;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

procedure init_faltpolygon;

begin

setlength(area_list, 1);
setlength(edge_list, 4);
setlength(point_list, 4);


point_list[0].x:=100;
point_list[0].y:=100;

point_list[1].x:=500;
point_list[1].y:=100;

point_list[2].x:=500;
point_list[2].y:=500;

point_list[3].x:=100;
point_list[3].y:=500;

edge_list[0].point1:=@point_list[0];
edge_list[0].point2:=@point_list[1];
edge_list[0].next_edge:=@edge_list[1];
edge_list[1].point1:=@point_list[1];
edge_list[1].point2:=@point_list[2];
edge_list[1].next_edge:=@edge_list[2];
edge_list[2].point1:=@point_list[2];
edge_list[2].point2:=@point_list[3];
edge_list[2].next_edge:=@edge_list[3];
edge_list[3].point1:=@point_list[3];
edge_list[3].point2:=@point_list[0];
edge_list[3].next_edge:=@edge_list[0];

area_list[1].edge:=edge_list[1];

end;


begin

init_faltpolygon;

end;

end.

bitsetter 29. Mär 2007 20:07

Re: Porblem mit Arrays, die Pointer auf Record sind
 
Hi,

ganz zum Schluss kommt der Fehler:

Original Code:
Delphi-Quellcode:
...
setlength(area_list, 1);
...
area_list[1].edge:=edge_list[1];
entweder du machst es so:
Delphi-Quellcode:
setlength(area_list, 2);
oder so:
Delphi-Quellcode:
area_list[0].edge:=edge_list[1];

darthdungeon 29. Mär 2007 20:13

Re: Porblem mit Arrays, die Pointer auf Record sind
 
ah mist, stimmt, danke, aber wieso stürt der dann beim beenden des programms ab und net schon beim starten?

pszopp 29. Mär 2007 21:14

Re: Porblem mit Arrays, die Pointer auf Record sind
 
Hallo darthdungeon,

Hast du bei den Compiler-Optionen den RangeCheck (Bereichsprüfung) passiv?
Dann prüft Delphi nicht, ob bei dyn. Arrays gültige Indizes benutzt werden. Dadurch schreibst du dir beim Start des Programms den Speicher kaputt. Beim Beenden des Programms wird auf fehlerhafte Speicherstellen zugegriffen und es wird eine Exception erzeugt.

Bei eingeschaltetem RangeCheck würde Delphi den Fehler sofort merken.

Gruß,
pszopp

3_of_8 29. Mär 2007 22:47

Re: Porblem mit Arrays, die Pointer auf Record sind
 
Delphi-Quellcode:
type
  TEdge =^PEdge;
  PEdge = record
  point1, point2: TPoints;
  next_edge: TEdge;
end;
Also das verwirrt mich.

Du deklarierst einen Record mit einem P-Präfix, das eigentlich für Pointer-Typen reserviert ist. Du rückst bei der Record-Felddeklaration nicht ein, aber du rückst das end; am Ende der Record-Deklaration aus. Und dann Deklarierst du einen Pointertypen mit T-Präfix, das für "normale" Typen reserviert ist.

Kleiner Tipp: So siehts besser aus:
Delphi-Quellcode:
type
  PEdge = ^TEdge;

  TEdge = record
    point1, point2: TPoints;
    next_edge: PEdge;
  end;

darthdungeon 30. Mär 2007 16:40

Re: Porblem mit Arrays, die Pointer auf Record sind
 
cool, das mit dem rangecheck kannste ich noch nich, geile sachen, danke!
und @Manuel Eberl: so kann man es auch machen^^


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:15 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz