Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wieso springt er in den Destruktor? (https://www.delphipraxis.net/85007-wieso-springt-er-den-destruktor.html)

schuetzejanett 24. Jan 2007 16:11


Wieso springt er in den Destruktor?
 
Hallo, habe eine Klasse DartField die die eckpunkte eines dartFeldes und den dazugehörigen Namen speichert und eine Klasse dartBoard die die ganzen DartFelder in eine Liste speichert.
Da es insgesamt 82 Dartfelder gibt habe ich diese in eine typisierte Datei geschrieben um sie beim anlegen des Dartboardes auslzulesen. Wenn ich jetzt allerdings von einer anderen klasse aus ein Dartboardobjekt erzeuge, springt er bei der Zeile
Delphi-Quellcode:
        DField.Region := CreatePolygonRgn(Points,4,winding);
ind den Destruktor der Klasse Dartboard anstatt die region anzulegen und zu speichern.
Warum? was mache ich falsch?

Delphi-Quellcode:
unit DartBoard;

interface

uses
  Classes, SysUtils, Dialogs, Windows, Contnrs;

type TPArray = Array [0..3] of TPoint;
      TField = packed record
        x1,y1,x2,y2,x3,y3,x4,y4 : integer;
        Name : String[4];
      end;

type TDartField = class(TObject)
  private
    FRegion: HRGN; // was auch immer das für ein Typ ist?
    FName: String;
  public
    property Region: HRGN read FRegion write FRegion;
    property Name: String read FName write FName;
  end;  

type TDartBoard = class(TList)
  private
    procedure initBoard;
    function GetPArray( x1,y1,x2,y2,x3,y3,x4,y4: integer) : TPArray;
    function GetDartField(Index: Integer): TDartField;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Add(Item: TDartField);
    function Next(AktField : Integer): TDartField;
    function IndexOf(Item: TDartField): Integer;
    property DartField[Index: Integer]: TDartField read GetDartField;
  end;

implementation

{ TDartBoard }

procedure TDartBoard.Add(Item: TDartField);
begin
  inherited Add(Item);
end;

constructor TDartBoard.Create;
begin
  inherited;
  initBoard;
end;

destructor TDartBoard.Destroy;
var
  i: Integer;
begin
  for i := 0 to self.Count - 1 do
    self.DartField[i].Free;
  inherited;
end;

function TDartBoard.GetDartField(Index: Integer): TDartField;
begin
   result := inherited Get(Index);
end;

function TDartBoard.GetPArray(x1, y1, x2, y2, x3, y3, x4,
  y4: integer): TPArray;
begin
  result[0] := Point(x1,y1);
  result[1] := Point(x2,y2);
  result[2] := Point(x3,y3);
  result[3] := Point(x4,y4);
end;

function TDartBoard.IndexOf(Item: TDartField): Integer;
begin
  result := inherited IndexOf(Item);
end;

procedure TDartBoard.initBoard;
var DField : TDartField;
    Points : TPArray;
    datei : file of TField;
    field : TField;
    i, Anz : integer;
begin
  AssignFile(datei,'Fields.dat');
  if FileExists('Fields.dat') then
    ReSet(datei)
  else ShowMessage('Datei für Dartboard nicht gefunden');
  For i := 0 to (FileSize(datei)-1) do
    begin
      seek(datei, i);
      Read(datei, field);
      Points := getPArray(field.x1, field.y1, field.x2, field.y2, field.x3,
                            field.y3, field.x4, field.y4);
      DField.Region := CreatePolygonRgn(Points,4,winding); //hier springt er in den Destruktor;
      DField.Name := field.Name;
      self.Add(DField);
    end;
  showmessage( inttostr(self.Count));
  CloseFile(datei);
end;

function TDartBoard.Next(AktField: Integer): TDartField;
begin
  if AktField = self.Count - 1 then
    result := self.Get(0)
  else
    result := self.Get(AktField + 1);
end;
end.

SirThornberry 24. Jan 2007 16:15

Re: Wieso springt er in den Destruktor?
 
in den destructor wird gesprungen wenn innerhalb des constructors ein Fehler auftritt. Da du innerhalb des Constructors InitBoard aufrust wird also der destructor aufgerufen wenn es innerhalb von InitBoard knallt.

NormanNG 24. Jan 2007 16:15

Re: Wieso springt er in den Destruktor?
 
Hi,

fehlt da nicht sowas?

Delphi-Quellcode:
DField := TDartField.Create;

schuetzejanett 24. Jan 2007 16:16

Re: Wieso springt er in den Destruktor?
 
Ja genau das wars, jetzt funktionierts danke für eure schnelle Hilfe;

Sunlight7 24. Jan 2007 23:20

Re: Wieso springt er in den Destruktor?
 
Moin!

Zitat:

Zitat von schuetzejanett
Delphi-Quellcode:
FRegion: HRGN; // was auch immer das für ein Typ ist?

Ein einfaches Handle zu einer Region :wink:

xaromz 25. Jan 2007 09:12

Re: Wieso springt er in den Destruktor?
 
Hallo,

mir ist noch aufgefallen, dass Du ein Speicherleck hast, weil Du die Regions nicht mehr freigibst.

Gruß
xaromz

SirThornberry 25. Jan 2007 10:30

Re: Wieso springt er in den Destruktor?
 
Zitat:

Zitat von xaromz
Hallo,

mir ist noch aufgefallen, dass Du ein Speicherleck hast, weil Du die Regions nicht mehr freigibst.

Gruß
xaromz

Das dachte ich auch mal. Die Hilfe und andere Forenuser haben mich dann eines besseren belehrt und meinten das man Regions einfach nicht frei geben darf/soll/muss wenn man sie einem Object zuweist.

xaromz 25. Jan 2007 11:30

Re: Wieso springt er in den Destruktor?
 
Hallo,
Zitat:

Zitat von SirThornberry
Das dachte ich auch mal. Die Hilfe und andere Forenuser haben mich dann eines besseren belehrt und meinten das man Regions einfach nicht frei geben darf/soll/muss wenn man sie einem Object zuweist.

das ist so leider falsch. Wenn Du z. B. einem Window eine Region übergibst, dann verwaltet das Window diese. Wenn Du jedoch einfach eine Region erzeugst, und diese nur in einem Delphi-Objekt speicherst, dann musst Du sie auch wieder freigeben.

Gruß
xaromz


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:00 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