Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem mit einem Zeiger... (https://www.delphipraxis.net/85093-problem-mit-einem-zeiger.html)

xZise 25. Jan 2007 21:09


Problem mit einem Zeiger...
 
Ich bin neu in die Zeiger eingestiegen und habe folgendes Konstrukt:

Das Formular:
Delphi-Quellcode:
type
  TfrmVariables = class(TForm)
    cbList: TComboBox;
    eName: TEdit;
    eValue: TEdit;
    {...}
    procedure cbListChange(Sender: TObject);
  private
     parser : ^TExCQParser;
  public
    {...}
    procedure setVariables(Data : TExCQParser);
  end;

procedure TfrmVariables.cbListChange(Sender: TObject);
begin
  eName.Text := parser^.Variables.Items[cbList.ItemIndex].Name; // <<<
  eValue.Text := FloatToStr(parser^.Variables.Items[cbList.ItemIndex].Variable.Values[0]);
end;

procedure TfrmVariables.setVariables(Data: TExCQParser);
var
   i : Integer;
begin
  parser := @Data;
   cbList.Clear;

   for i := 0 to parser^.Variables.Length - 1 do
  begin
    cbList.Items.Add(parser^.Variables.Items[i].Name);
  end;
end;
Jetzt tritt in cbListChange (Z. 17) der Fehler auf:
Zitat:

---------------------------
XXXX
---------------------------
Zugriffsverletzung bei Adresse 004626AA in Modul 'XXXX.exe'. Lesen von Adresse 00000030.
---------------------------
OK
---------------------------
Aufruf:
Delphi-Quellcode:
procedure TForm1.Button21Click(Sender: TObject);
begin
  frmVariables.Show;
  frmVariables.setVariables(Parser);
end;
Davor ist die Form nicht sichtbar, und die Funktion "setVariables" führt er ordnungsgemäß aus.

Wenn es nicht am Code liegt, werde ich mich wohl an den Programmierer des Parsers wenden müssen ;)

Der_Unwissende 25. Jan 2007 21:27

Re: Problem mit einem Zeiger...
 
Zitat:

Zitat von xZise
Wenn es nicht am Code liegt, werde ich mich wohl an den Programmierer des Parsers wenden müssen ;)

HI,
von welchem Typ ist denn dieser Parser. Schon klar, dass es sich um TExCqParser handelt, aber ist das eine Klasse oder ein Record? (gehe mal stark von ersterem aus). Wenn es eine Klasse ist, so wirst Du schon mal keinen Zeiger brauchen, da in der Variable Parser eh nur eine Referenz (ein impliziter Zeiger) übergeben wird.

Dein Fehler kann gleich durch verschiedene Dinge entstehen, aber am wahrscheinlichsten liegt es am falschen Index. Du greifst auf die Eigenschaft parser.Variables.Items zu, die dürften sich zwischen 0 und parser.Variables.Length - 1 liegen. Das prüfst Du aber nie. Für den Fall, dass noch kein Eintrag ausgewählt ist, dürfte der Index hier -1 sein und es könnte zu dem Fehler kommen. Dann prüfst Du auch nicht, ob ein Parser zugewiesen wurde (assigned(parser^)).

Ich gehe einfach mal davon aus, dass es sich bei dieser Prozedur um die Ereignisbehandlung eine Komponente handelt? Und genau hier dürfte eben dieses Ereignis schon beim Anzeigen aufgerufen werden (und der ItemIndex muss zu dem Zeitpunkt nicht gültig, der Parser nicht gesetzt sein). Also einfach vorher prüfen und nur wenn Du hier die Korrektheit sicherstellst den Inhalt ausführen.

Gruß Der Unwissende

Hawkeye219 25. Jan 2007 21:44

Re: Problem mit einem Zeiger...
 
Hallo Fabian,

der Fehler scheint ja heute sehr beliebt zu sein: klick
Bei dir steckt er in der Methode setVariables.

Gruß Hawkeye

marabu 26. Jan 2007 06:03

Re: Problem mit einem Zeiger...
 
Guten Morgen,

es könnte auch so sein: Das OnChange() der ComboBox wird beim Programmstart automatisch aufgerufen. Darin wird auf die Zeigervariable parser zugegriffen, bevor diese durch den Benutzer (Button21) initialisiert wird.

Delphi-Quellcode:
procedure TfrmVariables.cbListChange(Sender: TObject);
begin
  if Assigned(Parser) then
  begin
    eName.Text := Parser.Variables.Items[cbList.ItemIndex].Name;
    eValue.Text := FloatToStr(Parser.Variables.Items[cbList.ItemIndex].Variable.Values[0]);
  end else {...};
end;
Freundliche Grüße

Muehle 26. Jan 2007 07:49

Re: Problem mit einem Zeiger...
 
Ich glaube dein Problem kommt eher daher, das
du zu deiner Combo keinen Wert ausgewählt hast
-> cbList.ItemIndex=-1
und du bekommst eine Fehlermeldung.

Falls du Probleme mit Zeigern hast sinniere mal über diesen Code :

procedure test(testObj:TProjektLeistung; PtrObj:Pointer);

procedure TIrgendEinForm.test(testObj:TObject;PtrObj:Pointer ) ;

var p1,p2:^TObject;

begin
p1:=PtrObj;
p2:=Pointer(testObj);
assert(p1=p2);
end;

Aufruf erfolgt so :

o1:TObject;

test(o1,Pointer(o1));

xZise 26. Jan 2007 10:20

Re: Problem mit einem Zeiger...
 
Hi Unwissende, marabu und Muehle..
Ich denke das sollte sich auf alle beziehen:

Zitat:

Zitat von Der_Unwissende
Zitat:

Zitat von xZise
Wenn es nicht am Code liegt, werde ich mich wohl an den Programmierer des Parsers wenden müssen ;)

HI,
von welchem Typ ist denn dieser Parser. Schon klar, dass es sich um TExCqParser handelt, aber ist das eine Klasse oder ein Record? (gehe mal stark von ersterem aus). Wenn es eine Klasse ist, so wirst Du schon mal keinen Zeiger brauchen, da in der Variable Parser eh nur eine Referenz (ein impliziter Zeiger) übergeben wird.

Ich war mir nicht sicher ;) Und ein Zeiger auf einen Zeiger sollte doch funzen ^^ (und in setVars funzt es ja auch) Ich werds ändern ;)

Zitat:

Zitat von Der_Unwissende
Dein Fehler kann gleich durch verschiedene Dinge entstehen, aber am wahrscheinlichsten liegt es am falschen Index. Du greifst auf die Eigenschaft parser.Variables.Items zu, die dürften sich zwischen 0 und parser.Variables.Length - 1 liegen. Das prüfst Du aber nie. Für den Fall, dass noch kein Eintrag ausgewählt ist, dürfte der Index hier -1 sein und es könnte zu dem Fehler kommen. Dann prüfst Du auch nicht, ob ein Parser zugewiesen wurde (assigned(parser^)).

1. Der Typ der Liste ist, dass man dort nichts eintippen kann... d.h. es sind nur die Einträge möglich die in "setVars" gesetzt wurden. Und dazwischen habe ich eigentlich keine Funktion aufgerufen.
2. Ich werde mir dass absichern (<length> etc.)

Zitat:

Zitat von Der_Unwissende
Ich gehe einfach mal davon aus, dass es sich bei dieser Prozedur um die Ereignisbehandlung eine Komponente handelt? Und genau hier dürfte eben dieses Ereignis schon beim Anzeigen aufgerufen werden (und der ItemIndex muss zu dem Zeitpunkt nicht gültig, der Parser nicht gesetzt sein). Also einfach vorher prüfen und nur wenn Du hier die Korrektheit sicherstellst den Inhalt ausführen.

Also es ist der Code der Listbox (cbList), aber ich habe oben ja geschrieben, dass ich es absichern werde ^^

PS: Kanns ggf. daran liegen, dass diese Form, nicht die aufrufende Form kennt?

MfG
xZise

[edit]sry Hawkeye ^^ Ganz übersehen :P
Zitat:

Zitat von Hawkeye219
Hallo Fabian,

der Fehler scheint ja heute sehr beliebt zu sein: klick
Bei dir steckt er in der Methode setVariables.

Gruß Hawkeye

Also wie löst man das, dann?
Zitat:

Zitat von Hawkeye219
Hallo,

der Fehler dürfte hier stecken:

Delphi-Quellcode:
procedure TObjList.Add(AItem: TObject);
begin
  if FLength = FCapacity then
    Grow;
  FItems^[FLength] := PObject(@AItem);
  Inc(FLength);
end;
Du speicherst die Adresse einer lokalen Variablen (nämlich des Parameters) in der Liste. Diese Adresse ist nach dem Verlassen der Routine ungültig.

Gruß Hawkeye

[/edit]

[edit]Boar bin ich doof ^^ Ich muss doch nur die Instanzvariable speichern :D[/edit]


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:21 Uhr.

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