Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Delphi ändert Werte ohne Zuweisung oder Copy bei Dyn-Array (https://www.delphipraxis.net/60443-delphi-aendert-werte-ohne-zuweisung-oder-copy-bei-dyn-array.html)

fkerber 6. Jan 2006 23:21


Delphi ändert Werte ohne Zuweisung oder Copy bei Dyn-Array
 
Hi!

Edit: Anscheinend liegt es daran, dass Dyn. arrays nur Pointer sind....
aber wie kopieren???, ok, wohl mit copy, aber wie???

trotz save:= copy(kante,i+1,length(save)); (length von save gesetzt!) hängen sie noch voneinander ab!!!)


Vorab folgende Info:
Ich hatte vorher ein Record und wollte es zu einer Klasse umbauen, damit ich im noch ein paar Funktionen einbauen kann. Mit dem Record geht alles problemlos, aber seit es eine Klasse ist, geht alles drunter und drüber.

Also folgender Code:
Delphi-Quellcode:
type TKante = class(TObject)
 x1,x2: TPoint;
end;

var
  kante: array of TKante;
[...]
for i:=0 to length(kante)-1 do
 kante[i]:=TKante.Create;
dann in der Funktion, in der der Fehler auftritt (Zeilennummern zur Erläuterung in Klammern):
Delphi-Quellcode:
var save: array of TKante;
[...]
setlength(save,1);
save[0]:=Tkante.create;
//Wertzuweisung von save[0];
[...]
(1)    l:=1;
(2)    for k:=length(save)-1 downto 0 do
         begin
(3)       kante[i+l].x1:=save[k].x2;
(4)       kante[i+l].x2:=save[k].x1;
(5)       inc(l);
         end;
So, schauen wir uns den Inhalt von Save an:
nach Ausführung von...

(1) (((99, 221), (260, 231)))
(2) (((99, 221), (260, 231)))
(3) (((260, 231), (260, 231))) <===== !!!!!
(4) (((260, 231), (260, 231)))
[...] // Wert ändert sich nicht mehr


Was bitte geht hier vor??
Wie gesagt, bei Record keine Probleme!

Ciao Frederic

DevilsCamp 7. Jan 2006 00:28

Re: Delphi ändert Werte ohne Zuweisung
 
Erstmal:
Wie hängen deine beiden Codes von einander ab?
Sind die in einer Funktion? Wenn ja, auch beides innerhalb der for-Schleife aus dem ersten Quell-Code?



Zweitens:

das:
Delphi-Quellcode:
var save: array of TKante;
[...]
setlength(save,0);
save[0]:=Tkante.create;
funktioniert?

Durch die SetLength Anweisung hat das Array save doch die Länge 0. Wie kannst du da auf den Index 0 zugreifen?

fkerber 7. Jan 2006 00:39

Re: Delphi ändert Werte ohne Zuweisung
 
HI!

Zweitens zuerst:
Nein, das geht nicht, war ein abschreibfehler; habs geändert


mache jetzt ein

Delphi-Quellcode:
save:= copy(kante,i+1,length(save));

wenn ich aber Änderungen an Kante vornehm, z.B.
Delphi-Quellcode:
        kante[i+l].Free; //indezes korrekt, nur als Demo
        kante[i+l]:=Tkante.Create;
dann ist save danach auch alles leer....
Ich verstehs nicht!


Ciao Frederic

fkerber 7. Jan 2006 01:06

Re: Delphi ändert Werte ohne Zuweisung oder Copy bei Dyn-Arr
 
HI!

Sorry für Doppelposting, aber der übersichtlichkeit halber

Einfachestes Testprog:

Delphi-Quellcode:
type TKante = class(TObject)
 x1,x2: TPoint;
end;

type Tkantenarray= array of Tkante;

var
  Form1: TForm1;
  kante: TKantenarray;

[...]

procedure TForm1.Button1Click(Sender: TObject);
begin
setlength(kante,1);
kante[0]:=Tkante.Create;
kante[0].x1:=Point(0,1);
kante[0].x2:=Point(0,1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
 test: Tkantenarray;
begin
setlength(test,1);
test[0]:=Tkante.Create;
test:=copy(kante,0,1);
test[0].x1:=Point(80,80);
test[0].x2:=Point(80,80);
end;
Trotz Copy wirkt sich die Änderung von Test auf Kante aus...
Was tun?
Erneute Tests haben gezeigt, dass nicht die Arrays voneinander abhängen, sondern ihre Inhalte
also kante[0] und test[0], und das bei unterschiedlichen Speicheradressen :wall:
ich bekomm Kopfschmerzen :wall:



Ciao Frederic

Basilikum 7. Jan 2006 07:47

Re: Delphi ändert Werte ohne Zuweisung oder Copy bei Dyn-Arr
 
Delphi-Quellcode:
setlength(test,1);
test[0]:=Tkante.Create;
test:=copy(kante,0,1);
test[0].x1:=Point(80,80);
test[0].x2:=Point(80,80);
die Vorbereitungen (Zeile 1 + 2) machst Du mit Zeile 3 wieder zu nichten:
test:=Copy(kante,0,1) wird vom Compiler folgendermassen übersetzt:
SetLength(test,1);
test[0]:=kante[0];

womit Du dann frisch-fröhlich mit der selben Objekt-Instanz hantierst, auf die auch kante[0] zeigt - Object-Referenzen sind Zeiger auf die Objekte.... (Copy kopiert nicht die Objekte selber, sondern lediglich die Zeiger darauf)

fkerber 7. Jan 2006 09:30

Re: Delphi ändert Werte ohne Zuweisung oder Copy bei Dyn-Arr
 
HI!

Dieses Ergebnis tritt in der Tat ein, aber wieso?
Ich zitiere mal:

Zitat:

Wenn Sie im Gegensatz dazu eine unabhängige Kopie eines dynamischen Arrays erstellen möchten,
müssen Sie die globale Funktion Copy verwenden:

var
A, B: array of Integer;
begin
SetLength(A, 1);
A[0] := 1;
B := Copy(A);
B[0] := 2; { B[0] <> A[0] }
end;
Das stammt aus der Delphi-Hilfe....


Ciao Frederic

Jens Schumann 7. Jan 2006 10:01

Re: Delphi ändert Werte ohne Zuweisung oder Copy bei Dyn-Arr
 
Hallo,
die OH lügt hier auch nicht. Du hast in der Tat zwei unabhängige Array's.
Aber das unabhängig bezieht sich auf die Array's und nicht auf deren Inhalt.
Wenn Du Record speicherst ist klar, das mit Copy auch eine Kopie der Records
statt findet. Wenn Du Pointer in den Array's hast werden auch die Pointer
kopiert. Die Pointer zeigen aber weiterhin auf dieselbe Speicheradresse.
Objektreferenzen sind nicht anderes als Pointer!!!

fkerber 7. Jan 2006 10:22

Re: Delphi ändert Werte ohne Zuweisung oder Copy bei Dyn-Arr
 
HI!

Ja, das habe ich soeben durch die Google Groups auch herausgefunden...
Aber wie mache ich es dann? Wenn ich
Delphi-Quellcode:
         for i:=0 to high(test) do
         test[i]:=copy(kante[i]);
mache, sagt er mir: inkomaptible Typen....

Wie kann ich da ein Deep-Copy machen?


Ciao Frederic

SirThornberry 7. Jan 2006 10:25

Re: Delphi ändert Werte ohne Zuweisung oder Copy bei Dyn-Arr
 
Implementiere doch einfach noch eine "Assign"-Procedure bei deinem Object.

fkerber 7. Jan 2006 10:34

Re: Delphi ändert Werte ohne Zuweisung oder Copy bei Dyn-Arr
 
Hi!

Aber wie sollte die aussehen?

Delphi-Quellcode:
procedure assign(new: TKante);
begin
 self:=new;
end;
Das wird doch keine Änderung des Problems bewirken, oder?


Ciao Frederic


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:21 Uhr.
Seite 1 von 2  1 2      

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