Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi TStrings Speicher (https://www.delphipraxis.net/65977-tstrings-speicher.html)

Quake 23. Mär 2006 06:55


TStrings Speicher
 
Moin moin.

Ist das so richtig? Wenn ich in einem Form zwei ComboBoxen habe und in beiden Dropdownlisten den selben Inhalt haben möcht und dazu diese Zeile im Code Verwende
Delphi-Quellcode:
ComboBox2.Items=ComboBox1.Items
dass die Liste dann nur einmal im Speicher liegt?

Bernhard Geyer 23. Mär 2006 06:57

Re: TStrings Speicher
 
Zitat:

Zitat von Quake
Moin moin.

Ist das so richtig? Wenn ich in einem Form zwei ComboBoxen habe und in beiden Dropdownlisten den selben Inhalt haben möcht und dazu diese Zeile im Code Verwende
Delphi-Quellcode:
ComboBox2.Items=ComboBox1.Items
dass die Liste dann nur einmal im Speicher liegt?

Nein. Jede ComboBox muss/wird eine eigene Liste im Speicher halten. Das obige Konstrukt greift auf das Property Items zu und in der Setter-Methode wird die Stringliste kopiert.

Quake 23. Mär 2006 07:07

Re: TStrings Speicher
 
Wie kann ich das dann anstellen, dass die Liste nur einmal im Speicher gehalten wird? Irgendwie nur einen Pointer zuweisen?

xaromz 23. Mär 2006 07:14

Re: TStrings Speicher
 
Hallo,
Zitat:

Zitat von Quake
Wie kann ich das dann anstellen, dass die Liste nur einmal im Speicher gehalten wird? Irgendwie nur einen Pointer zuweisen?

Da wirst Du keinen Erfolg haben. Die Controls werden immer eigene Listen haben.

Gruß
xaromz

Bernhard Geyer 23. Mär 2006 07:15

Re: TStrings Speicher
 
Zitat:

Zitat von Quake
Wie kann ich das dann anstellen, dass die Liste nur einmal im Speicher gehalten wird? Irgendwie nur einen Pointer zuweisen?

Geht nicht, solange du die Default-ComboBox verwendest. Was würde wohl passieren wenn Du ComboBox1 freigeben würde? ComboBox1 würde seine eigene Liste freigeben und beim nächsten Zugriff von ComboBox2 würde es krachen da ja ComboBox2 versucht auf die freigegeben Liste zuzugreifen.

Was stört dich daran ein paar Zeilen Synchronisationscode zu schreiben? Du könntest Versuchen per Ownerdraw den Inhalt der einen ComboBox in der anderen zu zeichen, aber ob das einfacher ist?

Quake 23. Mär 2006 07:23

Re: TStrings Speicher
 
Das was mich stört ist die Speicherplatzverschwendung.

Luckie 23. Mär 2006 07:28

Re: TStrings Speicher
 
Also das was du da mehr an Speicher brauchst, ist im Vergleich zu deiner restlichen Anwendung wohl vernachlässigbar.

Quake 23. Mär 2006 07:39

Re: TStrings Speicher
 
Du weist ja nicht wie groß meine Stringliste ist :wink: . Sie kann bei mir schon ein paar 1000 Einträge haben.

xaromz 23. Mär 2006 07:49

Re: TStrings Speicher
 
Hallo,
Zitat:

Zitat von Quake
Du weist ja nicht wie groß meine Stringliste ist :wink: . Sie kann bei mir schon ein paar 1000 Einträge haben.

Nun ja. Bei 5000 Strings @ 20 Zeichen (plus 4 Byte Größe) sind das gerade einmal 120.000 Bytes (5000 * (20 + 4)), sprich 117 KB. Das sollte zu verschmerzen sein.

Gruß
xaromz

Quake 23. Mär 2006 07:57

Re: TStrings Speicher
 
Naja, bei 1GB Arbeitsspeicher wird es wenig ins Gewicht fallen. Aber wenn alle Programme so programmiert sind ist das schon schlecht. Aber gut, ich will hier keine Grundsatzdiskusion anfangen. Ich werd es dann wohl so machen müssen.

Vielen Dank an alle :thumb:
Martin

Grishnak 23. Mär 2006 08:01

Re: TStrings Speicher
 
Zitat:

Zitat von Quake
Du weist ja nicht wie groß meine Stringliste ist :wink: . Sie kann bei mir schon ein paar 1000 Einträge haben.

Du willst nicht im Ernst in einer Combo-Box über 1000 Einträgt zur Auswahl anbieten, oder? Wenn dem so ist, dann solltest du am grundlegenden Programm-Konzept etwas ändern.

Luckie 23. Mär 2006 08:07

Re: TStrings Speicher
 
Zitat:

Zitat von Quake
Naja, bei 1GB Arbeitsspeicher wird es wenig ins Gewicht fallen. Aber wenn alle Programme so programmiert sind ist das schon schlecht.

Ein Prozess hat 2 GB Adressraum zur Verfügung und abhängig vom vorhandenen Arbeitsspeicher, dazu ist ja die pagefile da. Aber wie mein Vorgänger shcon gesagt hat, was soll ein Benutzer mit 1000 einträgen in einer Combobox anfangen?

Quake 23. Mär 2006 08:07

Re: TStrings Speicher
 
Das ist schon richtig so. Es gibt ja auch die Möglichkeit im Editor-Feld was einzugeben quasi als Filter. Man muss ja nicht unbedingt scrollen :wink: . Ich will ja den Personen, die das bedienen sollen nur Tipparbeit ersparen

Ja ja, die guten alten C64 Zeiten, da musste man sich noch gedanken über die Programmierung machen :-D .

Grishnak 23. Mär 2006 08:19

Re: TStrings Speicher
 
Zitat:

Zitat von Quake
Ja ja, die guten alten C64 Zeiten, da musste man sich noch gedanken über die Programmierung machen.

Gut zu wissen, dass andere manchmal genau so denken, wie man selbst. :-D

jbg 23. Mär 2006 13:34

Re: TStrings Speicher
 
Die Delphi-Strings haben einen Referenzzähler. Und bei "S1 := S2;" wird nichts kopiert, sondern einfach S1 auf Pointer(S2) gesetzt und der Referenzzähler um eins erhöht. Beim kopieren einer Stringliste passiert genau dasselbe. Man braucht also grob Count*SizeOf(TStringItem) = Count*8 Bytes für die Kopie. Und bei 8KB sollten doch wohl noch drinnen sein.

Bernhard Geyer 23. Mär 2006 14:05

Re: TStrings Speicher
 
Zitat:

Zitat von jbg
Die Delphi-Strings haben einen Referenzzähler. Und bei "S1 := S2;" wird nichts kopiert, sondern einfach S1 auf Pointer(S2) gesetzt und der Referenzzähler um eins erhöht. Beim kopieren einer Stringliste passiert genau dasselbe. Man braucht also grob Count*SizeOf(TStringItem) = Count*8 Bytes für die Kopie. Und bei 8KB sollten doch wohl noch drinnen sein.

Wirt schon mehr sein da diese Strings auch im Win32-Control vorhanden sind/kopiert wurde und dort der Delphi-Referenzzähler nicht funktionieren kann da die Texte mit PChar-WinAPI-Funktionen kopiert wurden.

Quake 23. Mär 2006 14:12

Re: TStrings Speicher
 
Dann müste ich also statt
Delphi-Quellcode:
ComboBox2.Items:=ComboBox1.Items;
den Code
Delphi-Quellcode:
ComboBox2.Items[i]:=ComboBox1.Items[i];
in einen Schleife ausführen und für jeden String einzeln zuweisen und vorher ItemCount entsprechend setzen?

Geht dann nicht aber auch dieses:
Delphi-Quellcode:
ComboBox2.Items.Text:=ComboBox1.Items.Text;
:gruebel:

jbg 23. Mär 2006 14:14

Re: TStrings Speicher
 
Stimmt. Daran habe ich gar nicht gedacht, dass ComboBox.Items ja keine TStringList ist sondern eine TComboBoxStrings.

Bernhard Geyer 23. Mär 2006 14:20

Re: TStrings Speicher
 
Zitat:

Zitat von jbg
... dass ComboBox.Items ja keine TStringList ist sondern eine TComboBoxStrings.

Das hat damit nichts zu tun da TComboBoxStrings ein Nachfolger von TStringList und das Win32-Control davon nichts weis.

jbg 23. Mär 2006 14:26

Re: TStrings Speicher
 
Zitat:

Zitat von Bernhard Geyer
Das hat damit nichts zu tun da TComboBoxStrings ein Nachfolger von TStringList und das Win32-Control davon nichts weis.

Das wäre mir neu:

TCustomComboBoxStrings = class(TStrings);
TComboBoxStrings = class(TCustomComboBoxStrings);

Und TStrings speicher die Strings nicht selbst. TComboBoxStrings nutzt SendMessage um die Strings zu setzen bzw. zu lesen.

himitsu 23. Mär 2006 18:51

Re: TStrings Speicher
 
In einer StringListe gibt es keine einzelnen Strings, die Stringinhalte werden aller der Reihe nach in einen gemainsamen Speicherbereich geschrieben und per SLineBreak getrennt, also da ist nichts mehr mit einem Referenzzähler und gemeinsamem Speicher, welche sich zwei Strings teilen ... beim Aufruf von ComboBox2.Items[i] wird intern ja auch erst ein String erzeigt, in welchen dann die entsprechenden Stringdaten reinkopiert werden ... und wenn man einen String an ComboBox2.Items[i] übergibt, dann wird dessen inhalt ebenfalls in den großen, gemeinsamen Speicherbereich der Stringlist kopiert ... wie gesagt, egal wie ihr die Strings übergebt es sind und bleiben zwei unabhängige Speicherblöcke und demnach können die Daten nur Doppelt vorhanden sein.

jbg 23. Mär 2006 19:31

Re: TStrings Speicher
 
Zitat:

Zitat von himitsu
In einer StringListe gibt es keine einzelnen Strings

Und warum nutzt TStringList dann bitte schön ein "händisches" dynamisches Array of TStringItem? Die Text- und CommaText-Eigenschaft durchläuft dieses Array und baut die Strings zu einem Gesamtstring zusammen. Also kann hier die Referenzzählung greifen.

Bei TListBox und TComboBox wird aber keine TStringList benutzt sondern eine spezielle TListBoxStrings bzw. TComboBoxStrings. Und die überlässt die String-Verwaltung dem Windows Control. Hier greift die Referenzzählung natürlich nicht (außer man verwendet Unicode-Controls mit WideString).

himitsu 24. Mär 2006 09:29

Re: TStrings Speicher
 
Zitat:

Zitat von jbg
Und warum nutzt TStringList dann bitte schön ein "händisches" dynamisches Array of TStringItem? Die Text- und CommaText-Eigenschaft durchläuft dieses Array und baut die Strings zu einem Gesamtstring zusammen. Also kann hier die Referenzzählung greifen.

Also mir ist/war so, als wäre das genau andersrum, TStringItem baut doch auf TStrings/TStringList auf?
Und dort stehen die Strings alle in einer Reihe, da ist dann kein Platz merh, für die Refferenzzähler, Längenangaben und was sonst noch in so'nem LongString enthalten ist (neben dem reinem Text).

jbg 24. Mär 2006 11:07

Re: TStrings Speicher
 
Zitat:

Zitat von himitsu
Also mir ist/war so, als wäre das genau andersrum, TStringItem baut doch auf TStrings/TStringList auf?

Dann schau mal in den Quellcode von Classes.pas. TStringItem baut überhaupt nicht auf TStrings/TStringList auf. Das ist andersherum:

Code:
  PStringItem = ^TStringItem;
  TStringItem = record
    FString: string;
    FObject: TObject;
  end;
Zitat:

Und dort stehen die Strings alle in einer Reihe, da ist dann kein Platz merh, für die Refferenzzähler, Längenangaben und was sonst noch in so'nem LongString enthalten ist (neben dem reinem Text).
Und was ist dann das:
Code:
  PStringItemList = ^TStringItemList;
  TStringItemList = array[0..MaxListSize] of TStringItem;

  TStringList = class(TStrings)
  private
    FList: PStringItemList;
Einer von uns versteht das Konstrukt Array wohl im Moment nicht mehr. :mrgreen:

Bernhard Geyer 24. Mär 2006 11:24

Re: TStrings Speicher
 
Zitat:

Zitat von jbg
Zitat:

Zitat von Bernhard Geyer
Das hat damit nichts zu tun da TComboBoxStrings ein Nachfolger von TStringList und das Win32-Control davon nichts weis.

Das wäre mir neu:

TCustomComboBoxStrings = class(TStrings);
TComboBoxStrings = class(TCustomComboBoxStrings);

Und TStrings speicher die Strings nicht selbst. TComboBoxStrings nutzt SendMessage um die Strings zu setzen bzw. zu lesen.

OK. Hast mich überzeugt. Dachte aber das es nur einfach 'ne Ableitung des Ableitungswillens ist und nicht 'ne komplette andere Implementierung.

himitsu 24. Mär 2006 12:46

Re: TStrings Speicher
 
hmm, und ich dachte TStringList hat die Stringbehandlung von TStrings geerbt und nichts eigenes verwendet :shock:

jbg 24. Mär 2006 12:50

Re: TStrings Speicher
 
TStrings is eine anstrakte Klasse, die bis auf die nötigen Methodendeklarationen nichts wirkliches zu bieten hat.


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