Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Keine Kopie? (https://www.delphipraxis.net/210502-keine-kopie.html)

freimatz 4. Mai 2022 07:31


Keine Kopie?
 
Bislang dachte ich, dass dynamisches Arrays wie String behandelt werden. Also wenn diese irgendwohin übergeben werden, dass dann eine Kopie erstellt wird (sofern nötig). Nach Analysen in unsrem Code habe ich einen möglichst einfachen Test erstellt. Folgender Test macht mich ratlos:
Delphi-Quellcode:
unit TestArray;

interface

uses
  System.Classes,
  System.Generics.Collections;

implementation

procedure Test_Array1();
type
  TValueArray = array of Char;
var
  item: TValueArray;
  list: TList<TValueArray>;
begin
  list := TList<TValueArray>.Create();
  SetLength(item, 2);

  item[0] := '1';
  item[1] := '2';
  list.Add(item);
//Watch Name   Value
//list[0]   ('1', '2')

  item[0] := '5';
  item[1] := '4';
  list.Add(item);
//Watch Name   Value
//list[0]   ('5', '4')
end;

initialization

Test_Array1();
halt;

end.
Wir gingen bislang davon aus, dass bei der Übergabe bei "list.Add(item);" eine Kopie übergeben wird. Dem ist scheinbar nicht so.
Wo ist der Denkfehler? (D11)

Nachtrag:
Ich glaub ich habs: https://docwiki.embarcadero.com/RADS...amische_Arrays
Im Gegensatz zu Strings und statischen Arrays wird copy-on-write nicht für dynamische Arrays verwendet.

jaenicke 4. Mai 2022 08:26

AW: Keine Kopie?
 
Das klappt nur für statische Arrays (array[0..1] of Char), aber nicht für dynamische Arrays. Dynamische Arrays sind nur Pointer und werden auch nicht anders behandelt.

// EDIT:
Ja, dein Nachtrag stimmt.

Der schöne Günther 4. Mai 2022 08:53

AW: Keine Kopie?
 
Dynamische Arrays sind Referenztypen wie z.B. Interfaces oder Objekte.
Statische Arrays sind Wertetypen wie z.B. Records oder Zahlen.

Bei ersteren kopierst du den Zeiger, bei letzteren immer den kompletten Wert.

Das ist auch der Grund weshalb du z.B. bei einer
Delphi-Quellcode:
TList<T>.ToArray()
eine neues Array bekommst, sonst hättest du ja Zugriff auf den internen Speicher und könntest den beliebig verändern.

Benmik 4. Mai 2022 11:33

AW: Keine Kopie?
 
Zitat:

Zitat von freimatz (Beitrag 1505404)
Im Gegensatz zu Strings und statischen Arrays wird copy-on-write nicht für dynamische Arrays verwendet.

Wie ist dann der darauf folgende Satz zu verstehen: Deshalb werden diese nicht automatisch kopiert, bevor einem ihrer Elemente ein Wert zugewiesen wird.? Das klingt doch so, als würde nach Wertzuweisung doch kopiert, was dem nachfolgenden Beispiel widerspricht. Ist dieser Satz einfach falsch, oder worauf bezieht er sich?

freimatz 4. Mai 2022 12:26

AW: Keine Kopie?
 
Zitat:

Zitat von jaenicke (Beitrag 1505405)
// EDIT:
Ja, dein Nachtrag stimmt.

Danke:thumb:

Zitat:

Zitat von Der schöne Günther (Beitrag 1505406)
Dynamische Arrays sind Referenztypen wie z.B. Interfaces oder Objekte.

Und was sind dann Strings? :P
Das sind doch auch Referenztypen.

Und Dynamische Arrays sind nicht "wie z.B. Interfaces oder Objekte". Bei denen musst Du dich um die Erzeugung selber kümmern und teilweise auch um die Freigabe. Bei dynamischen Arrays musst Du das nicht (wie auch bei Strings). Wir finden das verwirrend. (https://en.wikipedia.org/wiki/Princi...t_astonishment)

Rolf Frei 4. Mai 2022 12:28

AW: Keine Kopie?
 
Ja meiner Meinung nach ist der Satz falsch oder halt unverständlich. Ein Dynamsicher Array ist wie eine String und verhält sich auch so. Wenn du den Array an eine Funktion mit einem var oder const Parameter übergibst, wird nur der Pointer darauf übergeben und nichts kopiert. Das ist gleich wie bei einem String. Der String /Array wird nur kopiert, wenn der Parameter kein const/var ist, z.B. hier: MyProc(myStr: String) / MyProc(myArray: TValueArray).

In deinem Fall von TList.Add ist der Parameter ein Pointer und daher wird da auch nichts kopiert, sondern einfach nur der Pointer auf den Array übegeben. Das Problem ist also nicht wirklich das Array, sondern die Funktion von TList, die du falsch verstanden hast.

freimatz 4. Mai 2022 16:50

AW: Keine Kopie?
 
Rolf, ich weiss jetzt nicht ob ich Dich verstanden habe. Für mich hört das was Du schreibst so an, als ob Du meinst, dass dynamische array und String gleich behandelt wird. Das stimmt nicht.
Es gilt für die Speicherverwaltung, man muss beide nicht erzeugen und freigeben. Für das automatische Kopieren gilt das nicht. Nochmals "Im Gegensatz zu Strings und statischen Arrays wird copy-on-write nicht für dynamische Arrays verwendet."
Wenn man bei dem obigen Testprogramm statt "array of Char" dann String verwendet, dann kommen andere Werte raus.

Rolf Frei 5. Mai 2022 12:47

AW: Keine Kopie?
 
Ja wir haben glaube ich etwas aneinander vorbeigeredet oder mein Verständnis von dynamischen Arrays war nicht ganz richtig. Deine Erkenntnis ist so richtig.

freimatz 5. Mai 2022 14:50

AW: Keine Kopie?
 
Mein Verständnis hat sich auch deutlich geändert diese Tage :-D
Zum Glück haben wir das in einem unit test bemerkt.
Und anderen Programmiersprachen ist das Verhalten von Typen meistens viel einheitlicher.


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