TObjectlist AccessViolation

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
starkard
Beiträge: 87
Registriert: Mi 31. Okt 2007, 10:44

TObjectlist AccessViolation

Beitrag von starkard »

Hallo Zusammen,

Arbeite gerade an einem kleinen Projekt und bin langsam am verzweifeln. Hoffe ihr könnt weiterhelfen. Ich möchte versuchen nicht zuweit auszuholen muss aber trozdem etwas mehr Code posten.

Im Programm verwende ich 2 Objektlisten als Container(FIFO) von Objekten einer Klasse, die sich je nach Bearbeitungsstatus im ersten oder zweiten zu finden sind.
Hierbei wird ein konkretes Obj. im der 1. Objektliste generiert, verarbeitet, landet dann im der 2. Objektliste, wird wiederum weiter verarbeitet und dann freigeben.

Bei der ersten Verarbeitung, welche mehrere Methoden umfasst, erhalte ich häufig (nicht immer) eine Zugriffsverletzung (EAccessViolation).
Erschwerend kommt hinzu dass das Programm auf einem Rechner läuft auf dem ich keine Entwicklungsumgebung habe und somit auf Terminalausgaben angewiesen bin.
(Würde auch gerne auf Remote Debugging etc. verzichten)

Code: Alles auswählen

procedure TSortierungFRM.Verarbeitungsroutine;
begin
...
  FListSpule.Add(FListMess.First as TStaemme); //Übertrag Obj. in 2. Liste
  FListMess.Delete(0)
...
  try
    GetStammPreis(FListSpule.Last as TStaemme); //Hier das Problemkind
  except
    on e: Exception do
    begin
      ...   
    end
  end;
 ...
end;
 
procedure TSortierungFRM.GetStammPreis(AStamm:TStaemme);
var
  sql:String;
begin
  if ((AStamm.isKurzholzPc=true) and (kurzPcLs.vId=0)) or
     ((AStamm.isKurzholzPc=false) and (langPcLs.vId=0)) then
    GetDefaultPreis(AStamm)
  else
  begin
    sql:=
      'SELECT vv_preisfm,vv_id FROM vorvertraege'+
      ' JOIN vorvertraegeumfang ON (vv_vid=v_id)'+
      ' WHERE v_id=:i_id'+
      ' AND :i_staerke BETWEEN vv_stvon AND vv_stbis'+
      ' AND vv_holzart=:i_holzart'+
      ' AND vv_holzqual=:i_holzqual';
    ZExec.Close;
    ZExec.SQL.Clear;
    ZExec.SQL.Add(sql);
    if AStamm.isKurzholzPc then
      ZExec.ParamByName('i_id').AsInteger:=kurzPcLs.vId
    else
      ZExec.ParamByName('i_id').AsInteger:=langPcLs.vId;
    ZExec.ParamByName('i_staerke').AsInteger:=AStamm.staerkeId;
    ZExec.ParamByName('i_holzart').AsInteger:=AStamm.holzartid;
    ZExec.ParamByName('i_holzqual').AsInteger:=AStamm.holzqualid;
    ZExec.Open;
    if not ZExec.IsEmpty then
    begin
      if ZExec.RecordCount>1 then DebugLn('Preisvorschlag>1 ');
      if not ZExec.FieldByName('vv_preisfm').IsNull then
        AStamm.preis:=ZExec.FieldByName('vv_preisfm').AsFloat*AStamm.festmeterGerundet;
      if not ZExec.FieldByName('vv_id').IsNull then
        AStamm.vvid:=ZExec.FieldByName('vv_id').AsInteger;
    end
    else
    begin
      GetDefaultPreis(AStamm);
    end;
  end;
  ZExec.Close;
end;


Die Übergabe von Objekten als Parameter sollten nicht gesondert behandelt werden müssen, da diese ledigich Pointer sind, richtig?
Es dürfte auch nicht an den DB-Operationen liegen, da wahrscheinlich EDatabaseError geworfen würde.
Ich kenne Zugriffsverletzungen wenn man z.b. versuchen würde auf ungültige Speicheradressen zuzugreifen. Nur wo??

Wäre für jede Antwort dankbar.

P.S. Windows XP Lazarus 0.9.28.2 FPC 2.4

Benutzeravatar
theo
Beiträge: 10500
Registriert: Mo 11. Sep 2006, 19:01

Re: TObjectlist AccessViolation

Beitrag von theo »

Wie sieht's denn mit OwnsObjects deiner Listen aus?
http://www.freepascal.org/docs-html/fcl ... jects.html

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: TObjectlist AccessViolation

Beitrag von Socke »

starkard hat geschrieben:Ich kenne Zugriffsverletzungen wenn man z.b. versuchen würde auf ungültige Speicheradressen zuzugreifen. Nur wo??

Richtig. Eine Zugriffsverletzung kann aber auch Folge von Zugriff auf gültigen Speicher in einem ungültigen Zusammenhang (bspw. über die Array-Grenzen hinaus schreiben) sein.
Daher: Alle Compiler-Checks in den Compiler-Optionen einschalten, die Unit heaptrc dort ebenfalls aktivieren.

Versuch doch ein

Code: Alles auswählen

if FListSpule.Last <> nil then
  GetStammPreis(FListSpule.Last as TStaemme);

um auszuschließen, dass die Adresse nil ist.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Antworten