Speicherlecks in TIniFile? [gelöst]
-
- 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?
@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
Re: Speicherlecks in TIniFile?
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 AufrufCode: 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.
-
- 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?
...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
Re: Speicherlecks in TIniFile?
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.
-
- 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?
...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
Re: Speicherlecks in TIniFile?
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;
-
- 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?
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
Re: Speicherlecks in TIniFile?
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.
-
- 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?
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
-
- 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?
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.
Immer mehr fange ich an zu begreifen, wie so ich früher mit vielen Shareware-Spiele/Programmen Ärger hatte.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
Re: Speicherlecks in TIniFile?
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.
Ü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).
-
- 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?
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
Mit Java und C/C++ sehe ich rot
-
- 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?
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 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
-
- 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]
" ein "end;" an der falschen Stelle platziert war,
Aus diesem Grund, ist es wichtig, das man die Source sauber strukturier.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- 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]
...wollen tät' ich ja schon gern....
Lazarus 1.6.4 32-Bit + 64-Bit, Windows 10 64-Bit, Manjaro Linux 64-Bit