Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi Inhalt einer TStringList in ein dynamisches String Array (https://www.delphipraxis.net/133577-inhalt-einer-tstringlist-ein-dynamisches-string-array.html)

HeikoAdams 5. Mai 2009 09:15


Inhalt einer TStringList in ein dynamisches String Array
 
Um den Inhalt einer TStringList in ein String Array zu kopieren, reicht folgende Funktion:
Delphi-Quellcode:
type
   TStringArray = array of string;

function CopyListToArray(List: TStringList): TStringArray;
var
  sCopyArray: TStringArray;
  nCount: Integer;
begin
  SetLength(sCopyArray, List.Count);

  for nCount := Low(sCopyArray) to High(sCopyArray) do
    sCopyArray[nCount] := List.Strings[nCount];

  Result := sCopyArray;
end;
Die Definition des Typs TStringArray ist notwendig, da Delphi keine arrays als Rückgabewert einer Funktion zu akzeptieren scheint.

mirage228 5. Mai 2009 09:23

Re: Inhalt einer TStringList in ein dynamisches String Array
 
Es sei noch anzumerken, dass, wenn man die Unit Delphi-Referenz durchsuchenTypes eingebunden hat, es bereits einen Typ Delphi-Referenz durchsuchenTStringDynArray gibt und dann die separate Definition überflüssig wird :)

Bernhard Geyer 5. Mai 2009 09:28

Re: Inhalt einer TStringList in ein dynamisches String Array
 
Und das arbeiten erst mit einer lokalen Variable bremmst du Angelegenheit nur.

Delphi-Quellcode:
function CopyListToArray(List: TStringList): TStringArray;
var
  nCount: Integer;
begin
  SetLength(result, List.Count);

  for nCount := Low(result) to High(result) do
    result[nCount] := List.Strings[nCount];
end;

himitsu 5. Mai 2009 09:41

Re: Inhalt einer TStringList in ein dynamisches String Array
 
Zitat:

Zitat von Bernhard Geyer
Und das arbeiten erst mit einer lokalen Variable bremmst du Angelegenheit nur.

Dynamische Arrays sollten ja eigentlich 'ne Referenzzählung besitzen
und das Result selber ist auch nur eine "lokale/temporäre" Variable :angel:

(Bezüglich der Exceptionbehandlung wird Result ja erst nach Funktionsende an die externe Variable übergeben)

Aber stimmt schon, wozu nocheine Variable, wo es doch eh an das Result geht.

Allerdings vermute ich hier den Einfluß von C und Co. wo mit Zuweisen des Return-Wertes die Funktion verlassen wird.

Bernhard Geyer 5. Mai 2009 09:45

Re: Inhalt einer TStringList in ein dynamisches String Array
 
Zitat:

Zitat von himitsu
Dynamische Arrays sollten ja eigentlich 'ne Referenzzählung besitzen

Wirklich? Wäre mir neu.

HeikoAdams 5. Mai 2009 09:47

Re: Inhalt einer TStringList in ein dynamisches String Array
 
Zitat:

Zitat von himitsu
Allerdings vermute ich hier den Einfluß von C und Co. wo mit Zuweisen des Return-Wertes die Funktion verlassen wird.

Nein, laut Delphi-Hilfe wird eine Funktion erst verlassen, wenn sie vollständig abgearbeitet wurde oder wenn eine Exit-Anweisung auftaucht.

Dax 5. Mai 2009 10:01

Re: Inhalt einer TStringList in ein dynamisches String Array
 
Zitat:

Zitat von Bernhard Geyer
Wirklich? Wäre mir neu.

Arrays und Strings sind referenzgezählt. Sonst müsste man die Arrays (wie auch die Strings, fwiw) explizit freigeben, was man ja nicht muss.

Luckie 5. Mai 2009 10:05

Re: Inhalt einer TStringList in ein dynamisches String Array
 
Zitat:

Zitat von HeikoAdams
Zitat:

Zitat von himitsu
Allerdings vermute ich hier den Einfluß von C und Co. wo mit Zuweisen des Return-Wertes die Funktion verlassen wird.

Nein, laut Delphi-Hilfe wird eine Funktion erst verlassen, wenn sie vollständig abgearbeitet wurde oder wenn eine Exit-Anweisung auftaucht.

Ich bin mir sicher, das himitsu das weiß. Aber der Code sieht mit der lokalen Variablen nach C/C++ aus und da wird mit return die Routine verlassen.

himitsu 5. Mai 2009 10:06

Re: Inhalt einer TStringList in ein dynamisches String Array
 
Zitat:

Zitat von Bernhard Geyer
Zitat:

Zitat von himitsu
Dynamische Arrays sollten ja eigentlich 'ne Referenzzählung besitzen

Wirklich? Wäre mir neu.

siehe FType.pas Abschnit "Compiler Intern Data-Types"

Delphi-Quellcode:
Const DynArrayInfo = SizeOf(Header); // Herader = RefCount + ElementCount
  MaxLengthOfMyType = (High(Integer) - DynArrayInfo) div SizeOf(TMyType);

Type TDynArrayInfo = packed Record
    RefCount:    LongInt;
    ElementCount: LongInt;
    Data:        packed Array[0..MaxLengthOfMyType-1] of TMyType;
  End;
und wie bekannt ist, zeigt der interne Pointer auf Data ...

PS: AnsiString und UnicodeString sind auch nur ein dynamisches Array (allerdings mit noch einem zusätzlichen 0#-Data-Feld am Ende) und WideString ist ein OLEStr

[add]
Zitat:

Aber der Code sieht mit der lokalen Variablen nach C/C++ aus und da wird mit return die Routine verlassen.
genau das meinte ich ... in Delphi ist das ja nicht so, aber viele übersetzen C-Code halt direkt und mit der nun "unnötigen" Temp-Variable

Bernhard Geyer 5. Mai 2009 10:08

Re: Inhalt einer TStringList in ein dynamisches String Array
 
Zitat:

Zitat von Dax
Arrays und Strings sind referenzgezählt. Sonst müsste man die Arrays (wie auch die Strings, fwiw) explizit freigeben, was man ja nicht muss.

Und was ist mit Widestrings (im Gegensatz zu String/UnicodeString)? Diese muss man nicht freigeben, sind aber nicht referenzgezählt :gruebel:

himitsu 5. Mai 2009 10:13

Re: Inhalt einer TStringList in ein dynamisches String Array
 
nein, WideStrings werden von der CompilerMagic an die WinAPI weiterrereicht und dann auch automatisch reservier/freigegeben, allerdings besitzen sie keine Referenzzählung,


also bei
Delphi-Quellcode:
Var S, S2: WideString;

S := S2;
wird nicht nur ein winziger Referenzzähler verändert, so wie bei Ansistring,
sondern es wird eine komplett neue Kopie des gesamten Strings angefertigt und an S übergeben.


[add]
Length wird sozusagen an SysStringLen weitergeleitet (wobei das optimiert wurde, da kurz vor dem OLEString die Größe steht, also wird diese einfach direkt ausgelesen und durch 2 geteilt, da Größe in Byte)

und der Rest wird an SysAllocStringLen, SysReAllocStringLen und SysFreeString
weitergeleitet,
also wenn eine WideString-Variable initialisiert/finalisiert oder irgendwo verändert wird

sirius 5. Mai 2009 10:20

Re: Inhalt einer TStringList in ein dynamisches String Array
 
Man könnte auch sagen, bei widestrings ist der imaginäre Referenzzähler immer 1. Und sobald eine Variable vom Typ WideString ihre Gültigkeit verliert wird der String freigegeben.


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