Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Frage zu TStringList (https://www.delphipraxis.net/117817-frage-zu-tstringlist.html)

kuba 25. Jul 2008 14:39


Frage zu TStringList
 
Hallo,

ich teste gerade mit TStringList ein paar Werte aus der Registry zu speichern.

Meine konkrete Frage : kann ich TStringList nur innerhalb einer Procedur verwenden ?

Mein (fehlerhafter) Code:

Delphi-Quellcode:
var
  sl       : TStrings;

procedure Portiere;
var
   zaehler  : integer;
   Registry : tRegistry;
   value    : string;
begin
   sl := TStringList.Create;
   for zaehler := 0 to 100 + 1 do
   begin
   Registry := tRegistry.Create;
  Try
    Registry.RootKey := HKEY_LOCAL_MACHINE;;
    Registry.OpenKey ('\Software\KUBA\Minimize', False);
    Value := Registry.ReadString (IntToStr(zaehler));
    sl.add(Value);
    Registry.CloseKey;
  Finally
    Registry.Free;
  End;
    //ShowMessage(sl[zaehler]);
  end;
    sl.Free;
end;

procedure ReadAll;
var
    zaehler  : integer;
    Value    : string;
begin
    sl := TStringList.Create;
    for zaehler := 0 to 100 + 1 do
    begin
    ShowMessage(sl[zaehler]);
    end;
    sl.Free;
end;

begin
    Portiere;
    ReadAll;
end.
KUBA

Die Muhkuh 25. Jul 2008 14:42

Re: Frage zu TStringList
 
Du zerstörst die StringList ja wieder, dann sind die Werte natürlich auch weg. Du darfst zwischen drin, also zwischen Portiere und ReadAll nicht zerstören. Am besten übergibst Du die StringList als var-Parameter.

Apollonius 25. Jul 2008 14:43

Re: Frage zu TStringList
 
Oder noch besser als const-Parameter.

kuba 25. Jul 2008 14:46

Re: Frage zu TStringList
 
Ich hatte es mir schon so gedacht :|

Delphi-Quellcode:
var
  sl       : TStrings;


procedure Portiere;
var
   zaehler  : integer;
   Registry : tRegistry;
   value    : string;
begin
   for zaehler := 0 to 100 + 1 do
   begin
   Registry := tRegistry.Create;
  Try
    Registry.RootKey := HKEY_LOCAL_MACHINE;;
    Registry.OpenKey ('\Software\KUBA\Minimize', False);
    Value := Registry.ReadString (IntToStr(zaehler));
    sl.add(Value);
    Registry.CloseKey;
  Finally
    Registry.Free;
  End;
    //ShowMessage(sl[zaehler]);
  end;
end;

procedure ReadAll;
var
    zaehler  : integer;
    Value    : string;
begin
    for zaehler := 0 to 100 + 1 do
    begin
    ShowMessage(sl[zaehler]);
    end;
end;

begin
    sl := TStringList.Create;
    Portiere;
    ReadAll;
    sl.Free;
end.
So geht´s, danke Muhmuh !! :cheers:

KUBA

Die Muhkuh 25. Jul 2008 14:46

Re: Frage zu TStringList
 
Resourcenschutzblöcke nicht vergessen ;)

Und als Parameter wäre es noch besser :zwinker:

Butch87 25. Jul 2008 14:48

Re: Frage zu TStringList
 
Zitat:

Zitat von Die Muhkuh
Resourcenschutzblöcke nicht vergessen

:wiejetzt: :wiejetzt: :wiejetzt: :wiejetzt: :wiejetzt:

DeddyH 25. Jul 2008 15:06

Re: Frage zu TStringList
 
Delphi-Quellcode:
procedure Portiere(const sl: TStrings);
var
   zaehler  : integer;
   Registry : tRegistry;
   value    : string;
begin
  Registry := tRegistry.Create;
  Try
    Registry.RootKey := HKEY_LOCAL_MACHINE;;
    if Registry.OpenKey ('\Software\KUBA\Minimize', False) then
      begin
        for zaehler := 0 to 100 + 1 do
          begin
            Value := Registry.ReadString (IntToStr(zaehler));
            sl.add(Value);
          end;
        Registry.CloseKey;
      end;
  Finally
    Registry.Free;
  End;
end;

procedure ReadAll;
var
    zaehler  : integer;
    Value    : string;
    sl       : TStringList;
begin
    sl := TStringlist.Create;
    try
      Portiere(sl);
      for zaehler := 0 to sl.Count - 1 do
        begin
          ShowMessage(sl[zaehler]);
        end;
    finally
      sl.Free;
    end;
end;

begin
    ReadAll;
end.
[edit] Hatte vergessen, den Parameter zu übergeben. [/edit]

p80286 25. Jul 2008 16:56

Re: Frage zu TStringList
 
Hallo zusammen,

ich hätte das so gelöst:
Delphi-Quellcode:
function Portiere: TStringlist;
var
  zaehler  : integer;
  Registry : tRegistry;
  value    : string;
  sl       : tstringlist;
begin
  sl:=tstringlist.create;
  Registry := tRegistry.Create;
  Try
    Registry.RootKey := HKEY_LOCAL_MACHINE;;
    if Registry.OpenKey ('\Software\KUBA\Minimize', False) then
      begin
        for zaehler := 0 to 100 + 1 do
          begin
            Value := Registry.ReadString (IntToStr(zaehler));
            sl.add(Value);
          end;
        Registry.CloseKey;
      end;
  Finally
    Registry.Free;
  End;
  result:=sl;
end;

procedure ReadAll;
var
    zaehler  : integer;
    Value    : string;
    sl       : TStringList;
begin
  try
    sl:=Portiere(sl);
    for zaehler := 0 to sl.Count - 1 do
        begin
          ShowMessage(sl[zaehler]);
        end;
  finally
    sl.Free;
  end;
end;

begin
    ReadAll;
end.
Voll daneben? oder Geschmackssache? Speicherverschwendung?

Gruß
K-H

Die Muhkuh 25. Jul 2008 16:57

Re: Frage zu TStringList
 
Voll daneben. Man sollte Objekte immer auf der Ebene freigeben, auf der man sie erzeugt und das ist bei Dir leider nicht der Fall ;)

Christian Seehase 25. Jul 2008 21:02

Re: Frage zu TStringList
 
Moin K-H,

um Manuels Aussage noch etwas zu präzisieren:
Die Variante funktioniert zwar (wobei, wie bei DeddyH der Resourcenschutzblock für CloseKey fehlt ;-)), aber wenn man ein Objekt als Rückgabewert einer Funktion nutzt, kann man einfach zu leicht Speicherlecks erzeugen.
Wenn man es so macht, wie Du es gezeigt hast, gehört das Try übrigens hinter den Funktionsaufruf, und nicht davor, denn wenn das Erzeugen des Objektes fehlschlägt, gibt es auch nichts freizugeben.

Die Übergabe als const-Parameter, wie bei DeddyH, ist wohl die sinnvollste Variante, da man hier am leichtesten die Übersicht waren kann, dass das Objekt auch wieder freigegeben wird, und auch nicht, wie bei var-, out- oder Wert-Parametern, versehentlich dem Parameter ein Objekt zuweisen kann.

Meiner Ansicht nach gibt es nur einen Ausnahmefall für diese Regel, nämlich wenn das Objekt von einer Methode erzeugt wird, dessen Klasse die zurückgegebenen Objekte selber verwaltet.
Als Beispiel führe ich hier gerne TListView.Items.Add an.
Diese Methode gibt ein neu erzeugtes Objekt zurück, aber die Klasse TListView verwaltet diese dann auch selber.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:19 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-2025 by Thomas Breitkreuz