Open Array: ist das normal ?

Für Fragen rund um die Ide und zum Debugger
mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Open Array: ist das normal ?

Beitrag von mschnell »

Code: Alles auswählen

type
  t1 = array of integer;
..
var
  a, b: t1;
..
  setlength (a, 3);
//  setlength (b, 3);
  a[0] := 6;
  a[1] := 7;
  a[2] := 8;
  b := a;
  b[2] := 9;
  Memo1.Lines.Add(inttostr(a[2]));
  Memo1.Lines.Add(inttostr(b[2]));


Ergebnis:


Das hätte ich nicht erwartet.

In Delphi passiert dasselbe.

-Michael

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

Unlike Long Strings, that get "split" when we change one of them (to get a unique copy), dynamic arrays keep pointed to the same area. A bit unexpected, perhaps, but at least we don't get delayed performance hits (like with Long Strings)...
Of course, since dynamic array contents are copied when we call SetLength, that's also all it takes (a call to SetLength) to create a unique copy of a dynamic array.


Von hier: http://www.drbob42.com/delphi4/dynarray.htm

creed steiger
Beiträge: 957
Registriert: Mo 11. Sep 2006, 22:56

Beitrag von creed steiger »

Probier mal statt
b:=a;

b:=copy(a);
und lass dich überraschen.

(Ich hab aber auch erst nachschauen müssen)

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Beitrag von mschnell »

theo hat geschrieben:Unlike Long Strings,


Ich hatte gedacht, es würde "copy on write" gemacht, wie bei Strings.

Gruß und Dank,

-Michael

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Beitrag von mschnell »

creed steiger hat geschrieben:Probier mal statt
b:=a;

b:=copy(a);
und lass dich überraschen.


in Wirklichkeit will ich garnicht kopieren. Ich hatte nur einen Test gemacht und mich gewundert :).

-Michael

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

mschnell hat geschrieben:Ich hatte gedacht, es würde "copy on write" gemacht, wie bei Strings.


Ich kann dein Erstaunen nachvollziehen, zumal man doch irgendwie im Kopf hat, dass die Dinger wie Long Strings funktionieren.
Aber die Compiler Fritzen werden sich schon was dabei gedacht haben, hoff ich mal ;-)

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

Ja, das hat was mit Zeigern zu tun und zwar ist das das gleiche wie bei einer klasse z.b.:
Klasse1.Name='Pluto';
Klasse2.Name='Theo';

Klasse:=klasse1;
writeln(klasse.name);
Klasse.Name:='Stern'.

was würde hier Passieren ?
richtig Klasse1.name würde hier geändert werden, weil es nur ein normaler Zeiger/Pointer ist

und genau das gleiche ist dir passiert mschnell du hast einfach nur ein Pointer "erzeugt" der auf b zeigt.

oder Sehe ich das jetzt Falsch ?
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

@Pluto:Bei Objekten ist es klar.

Nur ist ein dynamisches Array fast das gleiche wie ein langer String.
Wenn du aber AnsiStr1:=AnsiStr2 machst, dann kriegst du eine Kopie.
Das erstaunliche ist nun, dass DynArr1:=DynArr2 keine Kopie macht sondern auf den gleichen Speicherbereich zeigt.
Erst Copy or SetLength reserviert einen eigenen Speicherbereich für die Variable.

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

das ist das gleiche.
du kannst einen Array nicht so zuweisen:
DynArr1:=DynArr2
das ist immer ein Pointer, soviel wie ich weiß.
DynArr1 hat jetzt den gleichen wert wie DynArr2. wenn du jetzt DynArr1 änders du eigentlich nur DynArr2 und nicht DynArr1.

Das habe ich mal irgendwo gelesen, das das so sein soll.
du kannst nur einen String zuweisen:
str:=str;
oder einen integer aber halt keinen Array. egal ob statisch oder dynamisch
MFG
Michael Springwald

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Der pluto macht sich.
Intern wird ein dyn. Array wie in c direkt mit dem Speicherbereich angesprochen. Und dieses Verhalten wurde hier nach außen nicht "korrigiert".

Ist aber nach dem vorbild von Borland so entstanden. Es wäre sicherlich nicht das riesen Problem das der Compiler dort ein Copy macht. Aber hat Borland nun damals so angefangen und so wirds weiter gemacht.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

schön das ich auch mal recht habe....

ich sage ja immer wieder: ich habe Erfahrung *freu*
MFG
Michael Springwald

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Erfahrung hat aber was mit Wissen zu tun ;p lol
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

ja, das sage ich ja andauert.... also habe ich viel Wissen, wenn man so möchte *freu*
MFG
Michael Springwald

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

OMG.
Dann stell doch nicht andauernd so dumme Fragen wenn du soo viel Wissen hast. Nö Pluto du hast nicht viel Wissen.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Beitrag von mschnell »

pluto hat geschrieben:richtig Klasse1.name würde hier geändert werden, weil es nur ein normaler Zeiger/Pointer ist

und genau das gleiche ist dir passiert mschnell du hast einfach nur ein Pointer "erzeugt" der auf b zeigt.

oder Sehe ich das jetzt Falsch ?


Richtig,

Aber bei Strings ist das anders. Die machen "copy on write" obwohl sie eigentlich auch Zeiger (mit Zusatzinformationen) sind, genau wir dynamic arrays. Ist eben 'ne andere Art so etwas zu implementieren. Aber schon merkwürdig dass in Delphi / FP das eine so und das andere anders implementiert ist. Da muss man schon aufpassen.

-Michael

Antworten