Speicherlecks in TIniFile? [gelöst]

Rund um die LCL und andere Komponenten
and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Speicherlecks in TIniFile?

Beitrag von and4more »

@wp_xyz: Wie machst Du das mit unterschiedlichen Werten (String und Integer oder Float)? Werden die als String im Record gespeichert und dann per cast in die entsprechenden Typen transformiert?
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Speicherlecks in TIniFile?

Beitrag von wp_xyz »

and4more hat geschrieben:...ich hab' mir jetzt nochmal beide Programme angeschaut: Könnte es sein, dass der Grund für das seltsame Verhalten in der Deklaration liegt?

Code: Alles auswählen

 
...
  private
    { private declarations }
  public
    { public declarations }
      IniF:TIniFile;
      blDBisDa:Boolean;
...
 

und unter TFrmMain.Create der Aufruf

Code: Alles auswählen

 
...
  IniF:=TIniFile.Create(IniPfad+'ORC'+ext);
...
 

Muss ich das evtl. anders deklarieren?

Ich denke, das ist richtig so. Mit dem Speicherleck hat das nichts zu tun. IniF muss als public deklariert sein, damit die anderen Formulare IniF sehen können. Und das TIniFile.Create wird nur 1x aufgerufen, egal ob IniF als public, private oder protected deklariert ist.

Da von mehreren Formularen auf dieselbe Ini-Datei zugegriffen wird, würde ich IniF allerdings nicht als Element von TFrmMain deklarieren (weil damit jedes andere Formular FrmMain unter "uses" benötigt, was früher oder später zur Zirkularabhängigkeiten führt), sondern in eine globale Deklarations-Unit auslagern, die von allen in Frage kommenden Units ge-"use"-t wird.

Code: Alles auswählen

unit Globals;
 
interface
 
uses
  IniFiles;
 
var
  IniF: TIniFile = nil;
  // evtl auch andere gemeinsam genutzte Deklarationen
 
implementation
end.


Das hängt natürlich von der Komplität deines Programms ab. Aber generell ist es eine gute Idee, wenn man von der Unit-Architektur her dafür sorgt, dass die Formulare autark bleiben und keine anderen Formulare brauchen.

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Speicherlecks in TIniFile?

Beitrag von and4more »

...ok, guter Tipp, hatte ich eigentlich schon gemacht für einige andere Funktionen, allerdings eben nicht für alle. Habe jetzt für die Datenbank ein eigenes Datamodul erstellt und die Behandlung der INI-File in eine andere Unit ausgelagert. Am Verhalten des Programms hat es leider nix geändert, immer noch tonnenweise Speicheradressen in heaptrc. Aber letztlich ist die Implementierung sauberer.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Speicherlecks in TIniFile?

Beitrag von wp_xyz »

and4more hat geschrieben:@wp_xyz: Wie machst Du das mit unterschiedlichen Werten (String und Integer oder Float)? Werden die als String im Record gespeichert und dann per cast in die entsprechenden Typen transformiert?

Nein, das wird nichts konvertiert. Wenn ein Record-Element ein Float ist, dann ist es auch ein Float im Settings-Record. Nur falls ich den Wert irgendwo ausgeben oder anzeigen will, wird er in einen String konvertiert.

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Speicherlecks in TIniFile?

Beitrag von and4more »

...auch auf die Gefahr hin, dass das etwas out of topic ist würde mich da sehr interessieren, woher der Record beim Einlesen erkennt welcher Typ wohin gehört, denn der Record benötigt ja eine Struktur mit z. B. Section, Key und Value und letztlich sind ja diese Typen beim Record vorgegeben, sofern sie nicht als variant deklariert sind und die Ini-Datei kann ja unterschiedliche Werte aufnehmen.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Speicherlecks in TIniFile?

Beitrag von wp_xyz »

Code: Alles auswählen

type
  TSettings = record
    FloatParameter: Double;
    StringParameter: String;
    IntegerParameter: Integer;
  end;
 
var
  Settings: TSettings = (
    FloatParameter: 1.0;
    StringParameter: '';
    IntegerParameter: 0
  );
 
procedure ReadFromIni;
var
  ini: TIniFile;
  fs: TFormatSettings;
begin
  ini := TIniFile.Create('myprogram.ini');
  try
    fs := FormatSettings;
    fs.DecimalSeparator := '.';   // Float mit Dezimalpunkt speichern
    Settings.FloatParameter := ini.ReadFloat('Parameter', 'FloatParameter', Settings.FloatParameter, fs);
    { Achtung: Obiges geht erst mit fpc 3.1.1. Vorher kannst du das "fs" weglassen, bzw. die Zahl in einen String mit Dezimalpunkt konvertieren }
    Settings.StringParameter := ini.ReadString('Parameter', 'StringParameter', Settings.StringParameter);
    Settings.Integerparameter := ini.ReadInteger('Parameter', 'IntegerParameter', Settings.IntegerParameter);
  finally
    ini.Free;
  end;
end;
 
procedure WritetoIni;
var
  ini: TIniFile;
  fs: TFormatSettings;
begin
  ini := TIniFile.Create('myprogram.ini');
  try
    fs := Formatsettings;
    fs.DecimalSeparator := '.';
    ini.WriteFloat('Parameter', 'FloatParameter', Settings.FloatParameter, fs);
    // Achtung: obiges geht erst ab fpc 3.1.1. Vorher fs weglassen, oder als String einlesen und nach Double konvertieren.
    ini.WriteString('Parameter', 'StringParameter', Settings.StringParameter);
    ini.WriteInteger('Parameter', 'IntegerParameter', Settings.IntegerParameter);
  finall
    ini.Free;
  end;
end;

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Speicherlecks in TIniFile?

Beitrag von and4more »

Danke für das Beispiel. Also das übersteigt meinen programmiertechnischen Horizont bei Weitem, denn auch wenn ich das Beispiel verstehe sind da Funktionen, von denen ich noch nie was gehört habe, aber nochmal vielen Dank, sehr schönes Beispiel.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Speicherlecks in TIniFile?

Beitrag von wp_xyz »

and4more hat geschrieben:Danke für das Beispiel. Also das übersteigt meinen programmiertechnischen Horizont bei Weitem, denn auch wenn ich das Beispiel verstehe sind da Funktionen, von denen ich noch nie was gehört habe, aber nochmal vielen Dank, sehr schönes Beispiel.

Sorry, eigentlich sollte ich das auf sich beruhen lassen. Aber was verstehst du denn da nicht? Bis auf das Zeug mit den Formatsettings, was du auch weglassen kannst, geht es nur um TIniFile. Wenn du mit TIniFile arbeitest, gehe ich davon aus, dass du neben Create auch die Methoden ReadInteger/Float/String bzw. WriteInteger/Float/String kennst.

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Speicherlecks in TIniFile?

Beitrag von and4more »

Das ist wohl etwas verkehrt rübergekommen. Verstanden habe ich alles, es sind nur einige Funktionen drin von denen ich noch nie was gehört habe. Ansonsten ist mir alles klar. Aber danke für die Nachfrage.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Speicherlecks in TIniFile?

Beitrag von Mathias »

Bis auf das Zeug mit den Formatsettings, was du auch weglassen kannst,

Das wollte ich wissen, ich habe ein Ini-Test mit der Ländereinstellung CH und DE probiert.
In der DE-Version wird anscheinend ein ',' gemacht und be CG '.' .

Ich dachte, das Ini-Files so so intelligent und macht von Haus auf immer ein '.' und sei somit Länderübergreifen, aber so kann man sich täuschen. :evil:

Immer mehr fange ich an zu begreifen, wie so ich früher mit vielen Shareware-Spiele/Programmen Ärger hatte. :roll:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Speicherlecks in TIniFile?

Beitrag von wp_xyz »

Mathias hat geschrieben:Ich dachte, das Ini-Files so so intelligent und macht von Haus auf immer ein '.' und sei somit Länderübergreifen, aber so kann man sich täuschen. :evil:

Über Intelligenz kann man streiten... Ich finde es gerade so wie es ist richtig: Dezimalzahlen werden IMMER so dargestellt, wie es die Ländereinstellungen vorgeben. Wenn der User etwas anderes will, muss er sich selber darum kümmern. In fpc trunk kannst du auch - wie in meinem Code oben angedeutet - die gewünschten FormatSettings als optionalen Parameter bei der ReadFloat/WriteFloat Methode angeben (genauso bei DateTime etc).

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Speicherlecks in TIniFile?

Beitrag von Mathias »

Ich finde es gerade so wie es ist richtig: Dezimalzahlen werden IMMER so dargestellt, wie es die Ländereinstellungen vorgeben.

Ich würde es von Vorteil finden, wen in Konfigurations-Dateien (ini) der Punkt ein Punkt ist. Das was der Anwender dann auf dem BS sieht, ist was anderes.
Ärger ist somit vorprogrammiert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Speicherlecks in TIniFile?

Beitrag von and4more »

Sooo, ...um das Ganze zum Abschluss zu bringen zu guter Letzt auch noch die Lösung des Problems. Nach langem Suchen ist mir aufgefallen, dass beim "Close"-Befehl des Hauptfensters beim Code zu den "Aufräumarbeiten" ein "end;" an der falschen Stelle platziert war, was dazu führte, dass das Programm zum Abschuss nochmal versucht hatte Daten in die INI-Datei zu schreiben, die aber aufgrund von ".free" nicht mehr als Objekt existent war. Insofern ist eine Speicherzugriffsverletzung eine durchaus logische Konsequenz :wink: Tja, das größte Computerproblem befindet sich also vor dem Monitor. Nichtsdestotrotz nochmal vielen Dank an alle Beteiligten und insbesondere für die lehrreichen Tipps.
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Speicherlecks in TIniFile? [gelöst]

Beitrag von Mathias »

" ein "end;" an der falschen Stelle platziert war,

Aus diesem Grund, ist es wichtig, das man die Source sauber strukturier. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

and4more
Beiträge: 207
Registriert: Do 15. Nov 2012, 19:13
OS, Lazarus, FPC: Windows 10, Manjaro Linux, Lazarus 1.6.4 (32/64 Bit)
CPU-Target: 32 Bit / 64 Bit

Re: Speicherlecks in TIniFile? [gelöst]

Beitrag von and4more »

...wollen tät' ich ja schon gern....
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit

Antworten