![]() |
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:
Wir gingen bislang davon aus, dass bei der Übergabe bei "list.Add(item);" eine Kopie übergeben wird. Dem ist scheinbar nicht so.
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. Wo ist der Denkfehler? (D11) Nachtrag: Ich glaub ich habs: ![]() Im Gegensatz zu Strings und statischen Arrays wird copy-on-write nicht für dynamische Arrays verwendet. |
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. |
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:
eine neues Array bekommst, sonst hättest du ja Zugriff auf den internen Speicher und könntest den beliebig verändern.
TList<T>.ToArray()
|
AW: Keine Kopie?
Zitat:
|
AW: Keine Kopie?
Zitat:
Zitat:
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. ( ![]() |
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. |
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. |
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.
|
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 16:21 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