Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Funktion mit Rückgabe TStrings bzw TMemIniFile (https://www.delphipraxis.net/192941-funktion-mit-rueckgabe-tstrings-bzw-tmeminifile.html)

SneakyBagels 4. Jun 2017 10:52


Funktion mit Rückgabe TStrings bzw TMemIniFile
 
Ich schreibe gerade eine meiner Funktionen so um, dass der Rückgabewert TStrings entspricht.

Auszug
Delphi-Quellcode:
sl := TStringList.Create;
try
 IniFile_.GetStrings(sl); // TMemIniFile
 ...
 ...
 Result := sl;
 // STELLE 1
finally
 sl. Free;
 // STELLE 2
end;
Wenn ich an STELLE 1 Result.Text prüfe, befindet sich der Inhalt der Ini-Datei da drin.
An STELLE 2 jedoch ist Result leer.

Wie bekomme ich dieses Problem in den Griff?
Ich würde ja gerne das Ini-File als Rückgabewert nehmen aber ich wüsste nicht wie.

stahli 4. Jun 2017 11:16

AW: Funktion mit Rückgabe TStrings bzw TMemIniFile
 
Meine Hilfe (XE3) kennt TIniFile.GetStrings nicht.
Ich setze mal voraus, dass damit alle Textzeilen nach SL kopiert werden.

Mit SL.Free wird diese StringList wieder freigegeben.
Da Result und SL den gleichen Speicherbereich referenzieren, wird damit auch Result freigebenen.
Somit gibst Du einen gelöschten/ungültigen Verweis aus Deiner Funktion heraus.

Du könntest 3 Lösungsansätze wählen:

1) Du verzichtest auf SL.Free und gibst somit eine existierende Stringlist heraus.
Dann solltest Du aber das Ergebnis an anderer Stelle wieder freigeben, damit Du nicht ein Memoryleak erzeugst und den Speicher vollmüllst.

2) Du erzeugst Deine SL vor der Funktion und übergibst diese als Parameter.
Dann hat die Funktion (oder Prozedur) nur die Aufgabe, SL zu füllen, aber nicht zu erzeugen.
Der Vorteil zu 1) ist, dass klarer ist, wo SL wieder freigegeben werden muss.

3) Du könntest aus der Funktion auch nur den reinen Text als String heraus geben.
Delphi-Quellcode:
function MyFunc: String;
var
  sl: TStringList;
begin
  sl := TStringList.Create;
  try
    IniFile_.GetStrings(sl); // TMemIniFile
    ...
    ...
    Result := sl.Text;
  finally
    sl. Free;
end;
In dem Fall könntest Du einfach den Text weiter verarbeiten und musst Dioch nicht um die Speicherfreigabe kümmern.

nahpets 4. Jun 2017 11:21

AW: Funktion mit Rückgabe TStrings bzw TMemIniFile
 
Du erstellst in der Funktion eine Stringliste und gibst sie in der Funktion wieder frei.

Result ist aber nur ein Zeiger auf die Stringliste.

Eventuell sowas in der Art?
Delphi-Quellcode:
function HoleIniInhalt : TStringList;
begin
  Result := TStringList.Create;
  try
    IniFile_.GetStrings(Result); // TMemIniFile
    ...
    ...
    // STELLE 1
  finally
    // STELLE 2
  end;
end;

var
  sl : TStringList;
begin
  sl := HoleIniInhalt;
  ...
  // Machwas mit sl
  ...
  sl.Free;
end;
Oder:
Delphi-Quellcode:
procedure HoleIniInhalt(sl : TStringList);
begin
  try
    IniFile_.GetStrings(sl); // TMemIniFile
    ...
    ...
    // STELLE 1
  finally
    // STELLE 2
  end;
end;

var
  sl : TStringList;
begin
  sl := TStringList.Create;
  HoleIniInhalt(sl);
  ...
  // Machwas mit sl
  ...
  sl.Free;
end;
Sinngemäß schrieb stahli das ja auch schon.

p80286 4. Jun 2017 11:33

AW: Funktion mit Rückgabe TStrings bzw TMemIniFile
 
Zitat:

Zitat von stahli (Beitrag 1373418)
2) Du erzeugst Deine SL vor der Funktion und übergibst diese als Parameter.
Dann hat die Funktion (oder Prozedur) nur die Aufgabe, SL zu füllen, aber nicht zu erzeugen.
Der Vorteil zu 1) ist, dass klarer ist, wo SL wieder freigegeben werden muss.

Kann ich nur unterstützen. Sonst kann es passieren, daß "frei vagabundierende" Stringlisten durch den Speicher geistern.
(Ich hab auch mal gedacht, das sei eine gute Idee)

Gruß
K-H

Michael II 4. Jun 2017 13:03

AW: Funktion mit Rückgabe TStrings bzw TMemIniFile
 
Hallo SneakyBagels

wenn ich deinen Codeteil richtig interpretiere, dann willst du nach dem Laden eines TMemIniFiles gewisse Einträge überprüfen und eventuell ändern und dann mit diesen geänderten Daten weiter arbeiten.

Wenn dem so wäre, dann könntest du auch via GetStrings das File in eine TStringlist laden, diese Stringliste abändern und danach via SetStrings wieder zurückschreiben. [Einfach TMeinMemIniFile von TMemIniFile ableiten und TMeinMemIniFile.Create entsprechend erweitern.]

Der Vorteil wäre, dass du in deinem Programm sämtliche Schreib-/Lesezugriffe, welche dein TMemIniFile betreffen, so belassen könntest wie sie sind.

[ Wenn du jedoch aus dem TMemIniFile nur jeweils einen Teil in eine TStringList extrahieren und damit arbeiten willst, die Original Ini Datei jedoch inkl. der in der TStringList nicht enthaltenen Daten behalten willst, dann müsste man von Fall zu Fall entscheiden. ]

Gruss
Michael

freimatz 6. Jun 2017 15:17

AW: Funktion mit Rückgabe TStrings bzw TMemIniFile
 
Zitat:

Zitat von stahli (Beitrag 1373418)
M
1) Du verzichtest auf SL.Free und gibst somit eine existierende Stringlist heraus.
Dann solltest Du aber das Ergebnis an anderer Stelle wieder freigeben, damit Du nicht ein Memoryleak erzeugst und den Speicher vollmüllst.

2) Du erzeugst Deine SL vor der Funktion und übergibst diese als Parameter.
Dann hat die Funktion (oder Prozedur) nur die Aufgabe, SL zu füllen, aber nicht zu erzeugen.
Der Vorteil zu 1) ist, dass klarer ist, wo SL wieder freigegeben werden muss.

3) Du könntest aus der Funktion auch nur den reinen Text als String heraus geben.

4) Du könntest eine Stringliste nehmen, die auf TInterfacedObject basiert, also referenzzählend ist.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:39 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