Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   FreePascal (https://www.delphipraxis.net/74-freepascal/)
-   -   Unerklärliche Zugriffsverletzung (https://www.delphipraxis.net/212851-unerklaerliche-zugriffsverletzung.html)

MPeters 13. Apr 2023 08:23

Unerklärliche Zugriffsverletzung
 
Hallo,

ich bin gerade am Verzweifeln. Ich erhalte eine Zugriffsverletzung in folgendem Code:

Delphi-Quellcode:
constructor TVisibleTreeNode.Create(theParentBox:TAnchestorClass; theName,theImage:string; theX,theY:longint; theCaption:string);
var imgPtr: ImageType;
begin

  FParentBox := theParentBox;
  FName := theName;
  FLeft := theX;
  FTop := theY;
  FCaption := theCaption;
  FOnClick := @Click;

  imgPtr := LoadImage(theImage);
 
  FNodeImage := TVisibleNodeImage.Create(FParentBox,FName,FLeft,FTop,imgPtr.width,imgPtr.height,imgPtr,@ImageClick);
  inherited Create(FParentBox,FName,FLeft+FNodeImage.Width+6,FTop+7,theCaption);

  FClicked := false;
  FExpanded := false;

  FNode.VisibleClass := self; //AN DIESER STELLE DIE ACCESS VIOLATION
end;
Delphi-Quellcode:
  TVisibleTreeNode = class(TAnchestorClass)
  private
    FParentBox: TAnChestorClass;
    FLeft,
    Ftop,
    FWidth,
    FHeight: Integer;
   
    FName: String;
    FImage: String;
    FCaption: String;
    FClicked: Boolean;
    FExpanded: Boolean;
    FOnClick: TClickEvent;
    FNode: TNode;
    FNodeImage: TVisibleNodeImage;
   
    function GetCaption: String;
    procedure SetCaption(AValue: String);
    procedure SetImage(AValue: String);
    procedure SetLeft(AValue: Integer);
    procedure SetTop(AValue: Integer);
    procedure SetWidth(AValue: Integer);
    procedure SetHeight(AValue: Integer);
    procedure ImageClick(param: String);
  public
    constructor Create(theParentBox:TtuiBox; theName,theImage:string; theX,theY:longint; theCaption:string);

    procedure Click(Sender: TObject; mX, mY: Integer);
    property OnClick: TClickEvent read FOnClick write FOnClick;
  end;
Unten die Definition der Klasse und nun noch die Definition des Node:

Delphi-Quellcode:
  TNode = class(TObject)
  private
    FCompare: TCompareFunc;
    FCaption: String;
    FParent: TNode;
    FNext: TNode;
    FNumber: Integer;
    FSubnodes: TNodes;
    FVisibleClass: TObject;

    function GetCount: Integer;
    function GetNodes(Index: Integer): TNode;
  public
    constructor Create(aParent: TNode; CompareFunc: TCompareFunc; aCaption: String);
    destructor Destroy; override;

    procedure Add(ParentNode: TNode; aNode: TNode);
    procedure AddSubnode(aParentNode: TNode; aNode: TNode);                        //Neuen Sub Knoten hinzufügen

    property Caption: String read FCaption write FCaption;
    property Nodes[Index: Integer]: TNode read GetNodes;                         //Die Blätter
    property Count: Integer read GetCount;                                       //Anzahl Blätter
    property Parent: TNode read FParent write FParent;
    property Next: TNode read FNext write FNext;
    property Number: Integer read FNumber write FNumber;
    [B]property VisibleClass: TObject read FVisibleClass write FVisibleClass;[/B]
  end;
Warum tritt dese Zugriffsverletzung hier auf?

Klaus01 13. Apr 2023 08:26

AW: Unerklärliche Zugriffsverletzung
 
.. wo wird/wurde fNode denn erzeugt?

Grüße
Klaus

Renate Schaaf 13. Apr 2023 09:18

AW: Unerklärliche Zugriffsverletzung
 
Zitat:

.. wo wird/wurde fNode denn erzeugt?
genau,
und so
Zitat:

FOnClick := @Click;
kann man event handlers nicht zuweisen, lass mal das @ weg.

Renate

Delphi.Narium 13. Apr 2023 10:23

AW: Unerklärliche Zugriffsverletzung
 
Vor der Zuweisung von Self könnte man ja mal einfach prüfen, ob es FNode schon / überhaupt gibt:
Delphi-Quellcode:
if Assigned(FNode) then begin
  FNode.VisibleClass := self;
end else begin
  MessageDlg('Da hat jemand vergessen FNode zu erstellen.',mtError,[mbCancel],0);
end;
Oder per Haltepunkt und Debugger mal nachschauen, was da los ist.

DeddyH 13. Apr 2023 11:13

AW: Unerklärliche Zugriffsverletzung
 
Die Prüfung kann man sich aber auch sparen, da FNode ein privates Feld ist und somit im Konstruktor initial nil ist. Es bleibt also nur, die Instanz vor der Zuweisung zu erzeugen oder eine bereits bestehende als Argument dem Konstruktor hinzuzufügen. Bei Letzterem würde eine entsprechende Prüfung dann auch wieder Sinn machen.

MPeters 13. Apr 2023 18:04

AW: Unerklärliche Zugriffsverletzung
 
Zitat:

Zitat von Renate Schaaf (Beitrag 1520970)
Zitat:

.. wo wird/wurde fNode denn erzeugt?
genau,
und so
Zitat:

FOnClick := @Click;
kann man event handlers nicht zuweisen, lass mal das @ weg.

Renate

Ist schon Ok! In Delphi darf das "@" Zeichen da nicht stehen, in Freepascal jedoch muss es das.

MPeters 13. Apr 2023 18:06

AW: Unerklärliche Zugriffsverletzung
 
Zitat:

Zitat von Klaus01 (Beitrag 1520966)
.. wo wird/wurde fNode denn erzeugt?

Grüße
Klaus

Dake! Das war der Fehler. Nirgends wurde FNode erzeugt. Hatte ich beim Codieren übersehen und jetzt noch mal nachgeschaut. :wall:

MPeters 13. Apr 2023 18:12

AW: Unerklärliche Zugriffsverletzung
 
@Delphi.Narium +
Zitat:

Zitat von DeddyH (Beitrag 1520975)
Die Prüfung kann man sich aber auch sparen, da FNode ein privates Feld ist und somit im Konstruktor initial nil ist. Es bleibt also nur, die Instanz vor der Zuweisung zu erzeugen oder eine bereits bestehende als Argument dem Konstruktor hinzuzufügen. Bei Letzterem würde eine entsprechende Prüfung dann auch wieder Sinn machen.

Nun gut, mit so einer Prüfung hätte ich zumindest gesehen dass FNode noch gar nicht erzeugt wurde, was ja auch der Grund für die Exeption war. Ich war halt der Meinung, den FNode bereits in meinem Konstruktor erzeugt zu haben, was jedoch gerade nicht der Fall war. Erst jetzt aufgrund der Tipps hier noch mal im Konstriktor nach geschaut. Wald vor Bäumen nicht gesehen. Mehrmals vorher in den Konstruktor geguckt, aber die fehlende FNode Erzeugung war mir im Quellcode einfach nicht aufgefallen. Erst jetzt!

jaenicke 14. Apr 2023 08:09

AW: Unerklärliche Zugriffsverletzung
 
Zitat:

Zitat von MPeters (Beitrag 1521004)
Dake! Das war der Fehler. Nirgends wurde FNode erzeugt. Hatte ich beim Codieren übersehen und jetzt noch mal nachgeschaut. :wall:

Du hättest dann aber direkt beim Debuggen sehen müssen, dass der Wert nil ist, wenn du dort einen Haltepunkt setzt. :wink:


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