AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Zugriffsverletzung beim Zerstören der TIniFile-Instanz

Zugriffsverletzung beim Zerstören der TIniFile-Instanz

Ein Thema von TheSledgeHammer · begonnen am 26. Jan 2021 · letzter Beitrag vom 3. Feb 2021
Antwort Antwort
Seite 1 von 3  1 23   
freimatz

Registriert seit: 20. Mai 2010
1.490 Beiträge
 
Delphi 11 Alexandria
 
#1

AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz

  Alt 27. Jan 2021, 09:57
Hallo,
ich weiss jetzt nicht ob ich konkret weiterhelfen kann. Was ich bei so Problemen und wenn Konstruktoren oder Destruktoren fehlen mache: leite doch von TIniFile eine neue Klasse ab und verwende diese. Füge der Klasse jeweils ein Create und Destroy hinzu (mit inherited) und setze einen Breakpoint darauf. Manchmal kam es schon vor, dass man schon früher im Destroy vorbei kam als erwartet. Das spätere Free "knallt" dann zu recht.

Geändert von freimatz (27. Jan 2021 um 11:01 Uhr)
  Mit Zitat antworten Zitat
TheSledgeHammer

Registriert seit: 22. Mai 2019
Ort: Mulfingen
43 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz

  Alt 27. Jan 2021, 12:08
Hallo,
ich weiss jetzt nicht ob ich konkret weiterhelfen kann. Was ich bei so Problemen und wenn Konstruktoren oder Destruktoren fehlen mache: leite doch von TIniFile eine neue Klasse ab und verwende diese. Füge der Klasse jeweils ein Create und Destroy hinzu (mit inherited) und setze einen Breakpoint darauf. Manchmal kam es schon vor, dass man schon früher im Destroy vorbei kam als erwartet. Das spätere Free "knallt" dann zu recht.
Aus genau solchen Gründen hab ich mir angewöhnt, Variablen explizit auf NIL zu setzen und im Finally-Block nochmals explizit auf NIL zu prüfen. Die Ini-File-Instanz per se ist nicht das Problem hier. Eher, dass es innerhalb der DLL aufgerufen wird. Wir verwenden System.IniFiles an zig verschiedenen Stellen und noch nie kam es zu einem Fehler dieser Art. Die TForm-Komponente, die jetzt in der DLL ausgelagert ist, war früher in die Applikation mit rein kompiliert. Und in dieser Konstellation hat das jahrelang einwandfrei funktioniert.
Tobias
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.487 Beiträge
 
Delphi 12 Athens
 
#3

AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz

  Alt 27. Jan 2021, 12:28
Free prüft selbst ob die Variable bereits nil ist, dann passiert nichts.
TObject(nil).Free; // läuft problemlos
  Mit Zitat antworten Zitat
Benutzerbild von joachimd
joachimd

Registriert seit: 17. Feb 2005
Ort: Weitingen
684 Beiträge
 
Delphi 12 Athens
 
#4

AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz

  Alt 27. Jan 2021, 12:41
in Deinem Constructor fehlt ein
inherited Create(); sorry .... wurde ja schon angemerkt ....
Joachim Dürr
Joachim Dürr Softwareengineering
http://www.jd-engineering.de

Geändert von joachimd (27. Jan 2021 um 13:16 Uhr)
  Mit Zitat antworten Zitat
TheSledgeHammer

Registriert seit: 22. Mai 2019
Ort: Mulfingen
43 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz

  Alt 27. Jan 2021, 13:10
Um auf Blup's Post separat zu antworten:

1) Ich übergebe keine Strings. Auch keine WideStrings (auch wenn ich das hier das erste mal lese, aber ist logisch), sondern ich verwende PChar-typen. Das wird ja an unterschiedlichen Stellen so empfohlen, nicht zuletzt im Text des Code-Wizards:
Zitat:
Übergeben Sie String-Informationen mit PChar- oder ShortString-Parametern, um die Verwendung von BORLNDMM.DLL zu vermeiden.
2) DAS ist in der Tat interssant und eine komplette Neuheit für mich. ICh hab mich mit dem Thema TForms in DLLs schon einige Zeit befasst, aber DAS hab ich noch nirgends gelesen. Das sollte per se ja auch nicht das Thema sein, das einzubauen, ich hab ja einen "Konstruktor" in der DLL (ist nix anderes als eine Prozedur namens "CreateSearch"). Da hau ich den neuen Parameter mit rein, guter Punkt! Ist das aber dann nachher auch des Rätsels Lösung?

3) Ob du es glaubst oder nicht, es IST eine lokale Variable. Ich poste mal den gesamten Code:
Delphi-Quellcode:
procedure TFormDynamicSearchDialog.LoadIni;
var
  iniFile: TIniFile;
  sec: String;
begin

  if FIniFile <> 'then
  begin

    sec := 'Search';

    iniFile := nil;

    try

      iniFile := TIniFile.Create(FIniFile);

      miSqlLinkCmdAnd.Checked := iniFile.ReadBool(sec, miSqlLinkCmdAnd.Name, true);
      miSqlLinkCmdOr.Checked := iniFile.ReadBool(sec, miSqlLinkCmdOr.Name, false);

      if miSqlLinkCmdAnd.Checked then
        FSqlLinkCmd := slcAnd
      else if miSqlLinkCmdOr.Checked then
        FSqlLinkCmd := slcOr;

      case iniFile.ReadInteger(sec, pcMain.Name, 1) of
        0: tbFavourites.Click;
        1: tbExpert.Click;
        2: tbFavourites.Click;
      end;

    finally
      if iniFile <> nil then
        iniFile.Free;
    end;

  end else
  begin
    // if no INI has been defined, set SQL link command as default here
    miSqlLinkCmdAND.Checked := true;
    FSqlLinkCmd := slcAnd;
  end;

end;
Und bei dem "ShowModal" sollte man sich nicht verwirren lassen Das muss ich aber glaub genauer erklären. Im Interface zur Dll (Unit-Name "DynamicSearchDialogDllInterface") gibt es eine Methode, die "ShowModal" heißt. Diese wiederum ruft die aus der DLL exportierte Methode "ShowModal" auf (Unit-Name "DynSearchDialog"). Und in dieser Methode wird dann das tatsächliche "ShowModal" des TForm-Objekts aufgerufen (Unit-Name "DynamicSearchDialog"). D.h. ShowModal wird tatsächlich nur einmal aufgerufen, allerdings gibt es davor noch andere Methoden, die halt exakt so heißen. Hat was mit der Integration zu tun, ich wollte halt nicht, dass alle Entwickler ihren Code anpassen müssen, wenn sie auf die DLL umsteigen wollen; oder zumindest nur ganz gering anpassen müssen
Tobias

Geändert von TheSledgeHammer (27. Jan 2021 um 13:12 Uhr)
  Mit Zitat antworten Zitat
TheSledgeHammer

Registriert seit: 22. Mai 2019
Ort: Mulfingen
43 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz

  Alt 27. Jan 2021, 13:15
Wenn ich da mal noch einen Einfall anmerken dürfte. Ihr seht ja, dass ich die Ini-Datei-Instanz erzeuge, aber dafür einen im klassenweiten Kontext gültigen Wert verwende (FIniFile). Wie verhält sich das bei Ini-File-Objekten, wenn mehrere Instanzen auf ein und dieselbe physische Ini-Datei zugreifen? Wird da intern nur eine gültige Instanz erzeugt (so wie bei Interfaces) oder sind das mehrere Instanzen, deren Dateioperationen über eine Art Mutex synchonisiert werden?
Tobias
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.487 Beiträge
 
Delphi 12 Athens
 
#7

AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz

  Alt 3. Feb 2021, 11:06
Delphi-Quellcode:
procedure TFormDynamicSearchDialog.LoadIni;
var
  iniFile: TIniFile;
  sec: String;
begin

  if FIniFile <> 'then
  begin

    sec := 'Search';

    iniFile := nil;

    try

      iniFile := TIniFile.Create(FIniFile);

      miSqlLinkCmdAnd.Checked := iniFile.ReadBool(sec, miSqlLinkCmdAnd.Name, true);
      miSqlLinkCmdOr.Checked := iniFile.ReadBool(sec, miSqlLinkCmdOr.Name, false);

      if miSqlLinkCmdAnd.Checked then
        FSqlLinkCmd := slcAnd
      else if miSqlLinkCmdOr.Checked then
        FSqlLinkCmd := slcOr;

      case iniFile.ReadInteger(sec, pcMain.Name, 1) of
        0: tbFavourites.Click;
        1: tbExpert.Click;
        2: tbFavourites.Click;
      end;

    finally
      if iniFile <> nil then
        iniFile.Free;
    end;

  end else
  begin
    // if no INI has been defined, set SQL link command as default here
    miSqlLinkCmdAND.Checked := true;
    FSqlLinkCmd := slcAnd;
  end;

end;
Und bei dem "ShowModal" sollte man sich nicht verwirren lassen Das muss ich aber glaub genauer erklären. Im Interface zur Dll (Unit-Name "DynamicSearchDialogDllInterface") gibt es eine Methode, die "ShowModal" heißt. Diese wiederum ruft die aus der DLL exportierte Methode "ShowModal" auf (Unit-Name "DynSearchDialog"). Und in dieser Methode wird dann das tatsächliche "ShowModal" des TForm-Objekts aufgerufen (Unit-Name "DynamicSearchDialog"). D.h. ShowModal wird tatsächlich nur einmal aufgerufen, allerdings gibt es davor noch andere Methoden, die halt exakt so heißen. Hat was mit der Integration zu tun, ich wollte halt nicht, dass alle Entwickler ihren Code anpassen müssen, wenn sie auf die DLL umsteigen wollen; oder zumindest nur ganz gering anpassen müssen
Das Fehlerprotokoll zeigt eindeutig den rekursiven Aufruf von TDynamicSearchDialog.ShowModal und TFormDynamicSearchDialog.LoadIni.
Ausgelöst in TFormDynamicSearchDialog.LoadIni durch die Zeile "tbExpert.Click;".
  Mit Zitat antworten Zitat
TheSledgeHammer

Registriert seit: 22. Mai 2019
Ort: Mulfingen
43 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz

  Alt 3. Feb 2021, 14:26
Ja, eines dieser Fehlerprotokolle zeigt eine Rekursion, da geb ich dir Recht. Ich hab aber genau so viele Berichte mit Rekursion, wie solche, bei denen der Fehler nicht rekursiv geschieht, sondern wo es direkt beim ShowModal knallt. Ich hab - zugegeben - nicht geschaut, welchen Bericht ich da jetzt genommen hab, weil die Zeile, wo es knallt, exakt identisch ist. Ich kann dir aber beim besten Willen nicht sagen, warum in diesem Dump eine Rekursion enthalten ist... LoadIni() wird nur einmal aufgerufen...
Tobias
  Mit Zitat antworten Zitat
TheSledgeHammer

Registriert seit: 22. Mai 2019
Ort: Mulfingen
43 Beiträge
 
Delphi 10.3 Rio
 
#9

AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz

  Alt 27. Jan 2021, 13:33
Free prüft selbst ob die Variable bereits nil ist, dann passiert nichts.
TObject(nil).Free; // läuft problemlos
Dazu noch ein kleiner Einwurf: ja, für System-Komponenten mag das alles zutreffend sein. Ich vertrete allerdings die Meinung, dass man so viel Routine wie möglich, auf die einfachste Art und Weise wie möglich bekommen soll - keep the common case simple and fast.

Ihr glaubt gar nicht, wie häufig ich schon bei Konstruktor-Aufrufen Exceptions bekommen habe; daher stehen die immer innerhalb des Try-Blocks. Und ich unterscheide nicht zwischen System-Klassen und "eigenen", da wirst ja sonst kirre! Und v.a. bringst du so was keinem Azubi bei Und eine schlechte Idee ist es auch nicht, wenn man Konstruktoren "absichert"; da sind schon die dollsten Sachen bei passiert!

Vorm Destruktor auf NIL zu prüfen, i.O., das sehe ich ein, das mag bei Delphi durchaus so geregelt sein, aber wer aus der C++ Ecke kommt, gewöhnt sich ganz schnell an, Objekte vorm Zerstören auf Gültigkeit zu prüfen Und auch hier unterscheide ich nicht: das mach ich im besten Fall immer so, dann kann ich's im Zweifelsfall auch nicht vergessen. Routine, Routine, Routine...
Tobias
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.848 Beiträge
 
Delphi 12 Athens
 
#10

AW: Zugriffsverletzung beim Zerstören der TIniFile-Instanz

  Alt 27. Jan 2021, 14:08
Ihr glaubt gar nicht, wie häufig ich schon bei Konstruktor-Aufrufen Exceptions bekommen habe; daher stehen die immer innerhalb des Try-Blocks.
Dadurch zerschießt du dir den Speicher aber. Denn wenn dort eine Exception auftritt, ist die Variable gar nicht initialisiert. Es wird also ein Free auf einer pseudo-zufälligen Speicherstelle aufgerufen...

Du kannst ja außen herum noch einmal ein try..except setzen oder ähnliches, wenn du die Fehlerursache im Konstruktor nicht abstellen kannst, aber beim try..finally darf die Erstellung des Objekts aus dem genannten Grund nicht im try-Block stehen.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 11: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 by Thomas Breitkreuz