AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

EAccessViolation mit StringListe

Ein Thema von Edelfix · begonnen am 17. Mai 2017 · letzter Beitrag vom 17. Mai 2017
Antwort Antwort
Edelfix

Registriert seit: 6. Feb 2015
Ort: Stadtoldendorf
214 Beiträge
 
Delphi 10.4 Sydney
 
#1

EAccessViolation mit StringListe

  Alt 17. Mai 2017, 08:59
Hallo.

Ich habe eine Situation die ich leider nicht nachvollziehen kann.
Es geht um eine Access Vialotion in eine Quelcode Zeile die nur ab und zu kommt.
Ich konnte den Fehler noch nicht nachstellen. Nur Nachträglich im LogFile auslesen.

Die abgekürzte fassung der Funktion:

Delphi-Quellcode:
Function TDMAng.CheckRV(RD:TStringList;var errlist:TStringList):boolean;
begin
  result:=true;
  if not assigned(errlist) then errlist:=TStringList.Create;
  errlist.Clear;
  
  //viele Prüfungen ...
  
  if bPasstNicht then
    errlist.Add('"215","'+'Hinweis: '+'Passt nicht!')

  //viele Prüfungen...
   
  result:= errlist.count=0;
end;
Die Fehlermeldung:

madExcept version : 4.0.12
callstack crc : $00000000, $48d61ed6, $48d61ed6
exception number : 1
exception class : EAccessViolation
exception message : Zugriffsverletzung bei Adresse 00000000. Lesen von Adresse 00000000.

Dei Fehlerzeile ist mal "errlist.Clear;" oder "result:= errlist.count=0;".

Ich vermute das die Prüfung "if not assigned(errlist)" manchmal nicht greift.

Kann man die Funktion irgendwie optimieren?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.062 Beiträge
 
Delphi 12 Athens
 
#2

AW: EAccessViolation mit StringListe

  Alt 17. Mai 2017, 09:10
Der gezeigte Code-Teil an sich kann keinerlei Exceptions erzeugen, mit Ausnahme einer Einzigen, welche sich EOutOfMemory nennt.


Ich vermute das die Prüfung "if not assigned(errlist)" manchmal nicht greift.

Kann man die Funktion irgendwie optimieren?
Tja, dann hat wohl jemand außerhalb das errlist nicht orgendlich initialisiert, was man dann natürlich auch außerhalb beheben sollte, da es intern niemals einen sicheren Weg geben kann, um einen "defekten" Zeiger zu erkennen.



Pssst, ich glaub in deinem errlist.Add fehlt ein ", aber für den Fehler hier ist es egal.

Und bezüglich result:=true; sollte der Compiler auch was sagen, falls sich nicht irgendwo ein Exit; versteckt, aber auch erstmal egal.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (17. Mai 2017 um 09:14 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.582 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: EAccessViolation mit StringListe

  Alt 17. Mai 2017, 09:12
Wenn errlist manchmal einen ungültigen Zeiger enthält, liegt das vermutlich daran, dass diese übergebene Liste irgendwo mit Free freigegeben, die Variable aber weiter verwendet wird.

Wenn du dort stattdessen FreeAndNil benutzt, funktioniert auch die Prüfung mit Assigned.

Allerdings stimmt architektonisch dort etwas nicht, wenn manchmal, aber nicht immer, Instanzen in einer solchen Routine erzeugt werden. Für Erstellung und Freigabe muss immer jemand konkret zuständig sein, am besten in der gleichen Ebene (sprich z.B. nicht in einer Klasse die Erzeugung und in einer anderen die Freigabe).
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.354 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: EAccessViolation mit StringListe

  Alt 17. Mai 2017, 09:14
Delphi-Quellcode:
//Function TDMAng.CheckRV(RD:TStringList;var errlist:TStringList):boolean;
Function TDMAng.CheckRV(RD:TStringList;errlist:TStringList):boolean;
begin
  result:=true;
  if not assigned(errlist) then errlist:=TStringList.Create;
  errlist.Clear;
  
  //viele Prüfungen ...
  
  if bPasstNicht then
    errlist.Add('"215","'+'Hinweis: '+'Passt nicht!')

  //viele Prüfungen...
   
  result:= errlist.count=0;
end;
Erstmal das "var" beim Prozedurkopf für errlist rausnehmen. Das könnte das Problem schon beheben.
Ansonsten den Debugger nutzen und prüfen, wie die Inhalte sind und wo diese sich ändern und damit eine AV auslösen.

EDIT:
Den Unsinn mit dem "var" bitte ignorieren.
Peter

Geändert von Jasocul (17. Mai 2017 um 09:38 Uhr) Grund: Unsinn geschrieben
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.062 Beiträge
 
Delphi 12 Athens
 
#5

AW: EAccessViolation mit StringListe

  Alt 17. Mai 2017, 09:20
Erstmal das "var" beim Prozedurkopf für errlist rausnehmen. Das könnte das Problem schon beheben.
Dann hast du aber 100%ig in Zeile 2 ein Speicherleck.
Nein, wenn der Zeiger ungültig ist, dann bleibt er das auch, egal ob mit oder ohne Var, da sich innerhalb dieser Funktion rein garnichts ändert.

Und was jaenicke meint:
* entweder jemand in der gleichen Klasse kümmert sich um die Freigabe, oder garnichts erstellen
* oder wenn errlist Assigned ist, dann die Fehler loggen, bzw. ansonsten nur der Boolean-Result
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (17. Mai 2017 um 09:23 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.354 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: EAccessViolation mit StringListe

  Alt 17. Mai 2017, 09:37
Erstmal das "var" beim Prozedurkopf für errlist rausnehmen. Das könnte das Problem schon beheben.
Dann hast du aber 100%ig in Zeile 2 ein Speicherleck.
Asche auf mein Haupt. Du hast natürlich Recht.
Peter
  Mit Zitat antworten Zitat
SebastianZ

Registriert seit: 23. Jul 2009
89 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: EAccessViolation mit StringListe

  Alt 17. Mai 2017, 09:49
Hallo.

Ich habe eine Situation die ich leider nicht nachvollziehen kann.
Es geht um eine Access Vialotion in eine Quelcode Zeile die nur ab und zu kommt.
Ich konnte den Fehler noch nicht nachstellen. Nur Nachträglich im LogFile auslesen.

Die abgekürzte fassung der Funktion:

Delphi-Quellcode:
Function TDMAng.CheckRV(RD:TStringList;var errlist:TStringList):boolean;
begin
  result:=true;
  if not assigned(errlist) then errlist:=TStringList.Create;
  errlist.Clear;
  
  //viele Prüfungen ...
  
  if bPasstNicht then
    errlist.Add('"215","'+'Hinweis: '+'Passt nicht!')

  //viele Prüfungen...
   
  result:= errlist.count=0;
end;
Wie schon gesagt wurde, wird hier die Liste mit free vorderbei freigegeben.
Ich würde die Liste nicht als Var-Parameter übergeben. Dadurch ist nicht mehr ersichtlich wer die Hoheit über die Liste hat, und wer sie freizugeben hat.

Sauberer wäre aus meiner Sicht, du baust eine lokale Liste auf, gibst nur den String zurück, und fügst den String dann in die eigentliche Liste ein.

Also so in etwa:

Delphi-Quellcode:
function CheckRV(RD:TStringList; out ErrorText: String): Boolean;
var
  ErrorList: TStringList;
begin
  ErrorList := TStringList.Create;
  try
    result:=true;
  
    //viele Prüfungen ...
  
    if bPasstNicht then
      ErrorList.Add('"215","'+'Hinweis: '+'Passt nicht!')

    //viele Prüfungen...
   
    result:= ErrorList.count=0;
    ErrorText := ErrorList.Text;
  finally
    FreeAndNil(ErrorList);
  end
end;


procedure foo;
var
  lstError: TStringList;
  ErrorText: String;
begin
  lstError := TStringList.Create;
  try
    if not CheckRV(dummy, ErrorText) then
      lstError.Text := lstError.Text + ErrorText;

  finally
    FreeAndNil(lstError);
  end

end;
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: EAccessViolation mit StringListe

  Alt 17. Mai 2017, 10:21
Hallo,
Zitat:
Ich würde die Liste nicht als Var-Parameter übergeben. Dadurch ist nicht mehr ersichtlich wer die Hoheit über die Liste hat, und wer sie freizugeben hat.
100% Zustimmung.
Wer die Liste erzeugt, muss sie auch wieder freigeben.

Falls der Aufwand zu gross ist, dann sollte die Liste mit FreeAndNil freigegeben werden.

Zur Not hilft auch ein Singleton-Pattern,
um sicherzustellen, dass die StringListe wirklich nur einmal erzeugt wird.
Heiko
  Mit Zitat antworten Zitat
Edelfix

Registriert seit: 6. Feb 2015
Ort: Stadtoldendorf
214 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: EAccessViolation mit StringListe

  Alt 17. Mai 2017, 11:37
Danke an alle.


Ich werde den Vorschlag von SebastianZ ümsetzen.

Ich denke auch das ein String als Var-Parameter unproblematischer ist.

Vielen Dank.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:40 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