Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zugriffsverletzung bei Zuweisung eines Records (Feld) (https://www.delphipraxis.net/101165-zugriffsverletzung-bei-zuweisung-eines-records-feld.html)

Tormentor32 9. Okt 2007 11:15


Zugriffsverletzung bei Zuweisung eines Records (Feld)
 
Hallo Delphianer,

ich habe ein komisches Problem, welches ich nicht verstehe. Zunächst mal ein paar kurze Hintergrundinformationen: Ich habe ein Gerät, aus dem ich bestimmte Werte auslese, diese Werte bekomme ich als Zeichenkette, die ich dann aufdröseln muss um sie in einen Record abzulegen. Das klappt auch wunderbar.

Jetzt hab ich hier eine Funktion, die aus dem String die einzelnen Werte rausfiltert und in einen Record speichert
Delphi-Quellcode:
function TReplyParser.GetBrightnessStateStructFromSystemInfo(
  const ASystemInfo: string): TBrightnessStateStruct; //Das ist der Record, in dem die einzelnen Werte stehen
var
  hlp: TBrightnessStateStruct; //Hilfsvariable vom selben Typ
begin
  hlp.sensor_val := GetValueFromHex4Digits(copy(ASystemInfo,1,4));     //[1..4]
  hlp.solistrom := GetValueFromHex4Digits(copy(ASystemInfo,5,4));      //[5..8]
  //..... und so weiter, alle Wertzuweisungen
  // Der String hat definitiv die richtige Länge
  FBrightnessStateStruct := hlp; // Hier krachts! FBrightnessStateStruct ist eine private Variable vom Typ TBrightnessStateStruct und soll immer den letzten Status beinhalten.
  result := hlp; // aber das hier Kracht nicht! Wenn ich die Zeile eins drüber auskommentiere, dann klappt alles, es ist aber notwendig, dass die FBrightnessStateStruct Variable auch die Werte übernimmt
end;
Habe schon verschiedene Dinge ausprobiert, wie zum Beispiel alle Verweise auf FBrightnessStateStruct auszukommentieren aber jedes mal in dieser Funktion krachts, wenn ich ihr einen Wert zuweisen will.

Wäre super, wenn mir jemand sagen könnte woran das liegt, ich verstehe das einfach nicht!

Danke schonmal,

Ritsch

SirThornberry 9. Okt 2007 11:17

Re: Zugriffsverletzung bei Zuweisung eines Records (Feld)
 
wenn es dort kracht ist die Instanz von TReplyParser vermutlich nicht instanziert (das TReplyParser.Create(..)) vergessen.
Wenn du die Adressen angegeben hättest an denen es kracht könnte man das mit höherer Wahrscheinlichkeit sagen.

Tormentor32 9. Okt 2007 11:25

Re: Zugriffsverletzung bei Zuweisung eines Records (Feld)
 
Also erstmal danke für die Antwort! Dies hier ist die Fehlermeldung:

---------------------------
LDP 1 - Tool
---------------------------
Zugriffsverletzung bei Adresse 00478F76 in Modul 'pLDP1Tool.exe'. Schreiben von Adresse 0000001C.
---------------------------
OK
---------------------------

Ich habe gerade überprüft, ob der Konstruktor aufgerufen wird, das wird er definitiv, die Klasse wird beim Start des Programms instanziert und beim Beenden wird diese Instanz wieder freigegeben.

Ich musste nur gerade feststellen, dass die SELF Variable innerhalb der Funktion nil ist, wie ist das denn möglich? Ich müsste im Falle einer Nicht-Instanzierung doch schon einen Fehler kriegen, wenn ich die Funktion aufrufe oder?

:gruebel:

SirThornberry 9. Okt 2007 11:27

Re: Zugriffsverletzung bei Zuweisung eines Records (Feld)
 
die Adresse deutet auch darauf hinn das Self = nil ist also nicht instanziert wurde.

hast du eventuell
Delphi-Quellcode:
ReplyParser.Create(..);
geschrieben anstelle von
Delphi-Quellcode:
ReplyParser := TReplyParser.Create(..);
(der Variablenname ReplayParser ist nur Beispiel)
Zeig am besten mal die Stelle wo du das Create aufrufst.

Muetze1 9. Okt 2007 11:30

Re: Zugriffsverletzung bei Zuweisung eines Records (Feld)
 
Zitat:

Zitat von Tormentor32
Ich habe gerade überprüft, ob der Konstruktor aufgerufen wird, das wird er definitiv, die Klasse wird beim Start des Programms instanziert und beim Beenden wird diese Instanz wieder freigegeben.

Schön, und wo wird diese Instanz abgelegt? Anscheinend woanders als du später drauf zugreifst.

Zitat:

Zitat von Tormentor32
Ich musste nur gerade feststellen, dass die SELF Variable innerhalb der Funktion nil ist, wie ist das denn möglich? Ich müsste im Falle einer Nicht-Instanzierung doch schon einen Fehler kriegen, wenn ich die Funktion aufrufe oder?

Nein, dann würde Free() als Methode bei nil auch sofort eine Exception schmeissen anstatt die Funktionalität zu bringen, vorher Self auf Nil zu überprüfen und entsprechend zu entscheiden ob er Destroy aufruft oder nicht.

Du bekommst erst ein Problem, wenn du auf Elemente der Klasse zugreifst - wie du ja merkst. Also die Methode wird definitiv von einer nicht initialisierten Instanz aufgerufen. Entweder geschieht der Aufruf vor der Instanziierung oder du benutzt eine falsche Variable und greifst somit nicht (wie gedacht) auf die instanziierte Version zu.

Tormentor32 9. Okt 2007 11:47

Re: Zugriffsverletzung bei Zuweisung eines Records (Feld)
 
Mein Gott, wie kann man nur so blöd sein! :wall:

Delphi-Quellcode:
constructor TLDP1Controller.Create;
begin
  inherited Create;
  FReplyParser := TReplyParser.Create;
  FConnectionHandler := TConnectionHandler.Create(FReplyParser);
  FCommandHandler := TCommandHandler.Create(FConnectionHandler);
end;
Delphi-Quellcode:
constructor TConnectionHandler.Create(AReplyParser: TReplyParser);
begin
  inherited Create;
  FComPort := TComPort.Create(FComPort);
  FComPort.FlowControl.ControlDTR := dtrHandshake;
  FComPort.FlowControl.ControlRTS := rtsHandshake;
  FComPort.BaudRate := br19200;
  FComPort.Parity.Bits := prEven;

  FReplyParser := AReplyParser;//DAS HIER VERGESSEN!!!!!
  FComPort.StopBits := sbOneStopBit;
  FTimeout := 5000;
end;
Jetzt ist auch klar, warum ich von der TLDP1Controller Instanz zugreifen konnte, aber von FConnectionHandler nicht... oh Mann, da hätte ich aber auch selber drauf kommen müssen! :wall:

Was mich aber nicht verstehe ist, dass ich auf die Funktion zugreifen konnte, ohne Fehler, weil die Klasse ja garnicht instanziert war... was ihr ja schon vermutet habt.

Auf jeden Fall danke, für den Augenöffner :stupid:

SirThornberry 9. Okt 2007 12:44

Re: Zugriffsverletzung bei Zuweisung eines Records (Feld)
 
du kannst methoden etc. immer aufrufen solange nicht auf Dinge der Instanz zugegriffen wird. Grund ist das eine Methode intern so aussieht:
Delphi-Quellcode:
procedure DeineMethode(Self: TYourClass; eigentliche Parameter);
begin
  //
end;
Intern ist es also eine ganz normale Procedure welche die Objectinstanz übergeben bekommt. Und solange du nicht auf Self (was nil ist) zugreifst klappt alles weil ja alles initialisiert ist.

rufst du also
Delphi-Quellcode:
DeinObject.DeineMethode(eigentliche Parameter);
auf sieht das intern so aus:
Delphi-Quellcode:
DeineMethode(DeinObject, eigentliche Parameter);

Tormentor32 9. Okt 2007 12:51

Re: Zugriffsverletzung bei Zuweisung eines Records (Feld)
 
Vielen Dank für die Erklärung, man lernt doch nie aus! :mrgreen:


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