Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Kann man statische Arrays so gleichsetzen? (https://www.delphipraxis.net/182204-kann-man-statische-arrays-so-gleichsetzen.html)

Bjoerk 9. Okt 2014 09:45

Delphi-Version: 2007

Kann man statische Arrays so gleichsetzen?
 
Ich hab in meiner Software mehrere Statische Arrays. Hab gesehen daß ich die teilweise so gleichsetze. Bin gerade unsicher ob das überhaupt geht? Es soll keine Kopplung sondern ein Copy stattfinden.

Delphi-Quellcode:
type
  TFemVec3 = array [0..cMaxElemCount - 1] of double;

  TCustomFem = class
    ..
  protected
    FC: TFemVec3;
    FCopyOfC: TFemVec3;
    ..
  end;
Delphi-Quellcode:
procedure TCustomFem.CalcPlatte;
var
  I, Wdh: integer;
begin
  FCopyOfC := FC; // ****************
  Wdh := 0;
  repeat
    Inc(Wdh);
    NullA;
    for I := 1 to FemMaxN do
    begin
      FX[I] := 0;
      FB[I] := 0;
    end;
    for I := 1 to FSB do
    begin
      Set_SmLc_Platte(I);
      Load_G_Platte(Fm1[I], Fm2[I], Fm3[I], Fm4[I]);
    end;
    for I := 1 to FnUZ do
    begin
      Set_SmLc_Stab(I);
      Load_G_Platte(Fm1[FElemUZ[I]], Fm2[FElemUZ[I]], Fm3[FElemUZ[I]], Fm4[FElemUZ[I]]);
    end;
    Set_Last_Platte;
    Solve;
  until (Wdh = 3) or (not HaveAbhebendeElementeMitBettung);
end;

DeddyH 9. Okt 2014 09:57

AW: Kann man statische Arrays so gleichsetzen?
 
IIRC werden per CopyOnWrite lediglich die Werte kopiert, d.h. beide Arrays hängen nicht zusammen. Machen wir doch zur Sicherheit ein kleines Testprojekt:
Delphi-Quellcode:
procedure TFormTest.Button1Click(Sender: TObject);
type
  TMyArray = array[1..2] of integer;
var
  Original, Kopie: TMyArray;
begin
  Original[1] := 100;
  Original[2] := 1;
  Kopie := Original;
  (* Kopiertes Array ausgeben *)
  ShowMessage(Format('%d, %d', [Kopie[1], Kopie[2]]));
  Kopie[2] := 42;
  (* Werte aus Original und geänderter Kopie *)
  ShowMessage(Format('Original: %d, %d; Kopie: %d, %d',
    [Original[1], Original[2], Kopie[1], Kopie[2]]));
end;

Der schöne Günther 9. Okt 2014 09:59

AW: Kann man statische Arrays so gleichsetzen?
 
Genau so ein Testprojekt hatte ich auch grade einbringen wollen, aber der rote Kasten war schneller. Dann halt nur noch das Zitat auzs dem DocWiki:

Zitat aus dem DocWiki:

Zitat:

Unlike strings and static arrays, copy-on-write is not employed for dynamic arrays, so they are not automatically copied before they are written to. For example, after this code executes:
Delphi-Quellcode:
 var
   A, B: array of Integer;
   begin
     SetLength(A, 1);
     A[0] := 1;
     B := A;
     B[0] := 2;
   end;
the value of A[0] is 2. (If A and B were static arrays, A[0] would still be 1.)

Uwe Raabe 9. Okt 2014 10:00

AW: Kann man statische Arrays so gleichsetzen?
 
Zuweisungen von statischen Arrays verwenden wie bei Strings das copy-on-write. Insofern verhält es sich so, wie du es erwartest. Bei dynamischen Arrays ist das allerdings anders.

Edit: Der rote Kasten war offensichtlich gerade bei Günther...

Bjoerk 9. Okt 2014 10:11

AW: Kann man statische Arrays so gleichsetzen?
 
OK. Vielen Dank. Hab' fast schon einen mittleren Herzkasper gehabt..

himitsu 9. Okt 2014 16:33

AW: Kann man statische Arrays so gleichsetzen?
 
Statische Arrays werden sofort kopiert, genauso wie Records, Integer usw.

Was die Felder in den Records und statischen Arrays betrifft, da kommt es drauf an.
> Bei Strings wird nur der Referenzzeiger kopiert und die Referenzzählung hochgezählt, aber wenn man einen String verändert, dann wird er nur in dem entsprechenden Array geändert (CopyOnWrite).

Bei dynamischen Arrays wird nur der interte Zeiger kopiert und die Referenzzählung des Arrays hochgezählt.
Leider ist bei dynamischen Arrays das CopyOnWrite schon immer deaktiviert/futsch, womit bei Schreibzugriffen, auf den Array-Inhalt, das Arrays nicht automatisch kopiert wird, wenn der Referenzzähler größer 1 ist.

Wenn man also dynamische Arrays kopieren und die Inhalte "unabhängig" ändern will,
dann muß man das wirklich kopieren.
Delphi-Quellcode:
MeinString2 := MeinString2;
UniqueString(MeinString2); // das macht Delphi ja automatisch. (für Arrays ist diese Funktion aber nicht öffentlich zugänglich)
MeinString2[123] := 'a';

MeinDynamischesArray2 := Copy(MeinDynamischesArray1); //MeinDynamischesArray2 := Copy(MeinDynamischesArray1, 0, High(MeinDynamischesArray1));
MeinDynamischesArray2[123] := ...;

MeinStatischesArray2 := MeinStatischesArray1;
MeinStatischesArray2[123] := ...;

MeinRecord2 := MeinRecord1;
MeinRecord2.abc := ...;


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