![]() |
dynamische Array kopieren (letztes Element fehlt)
hallo,
ich arbeite seit kurzem mit dynamischen Arrays (vorher immer mit statischen) - also bin Anfänger ;) - und nun wollte ich ein komplettes Array in ein anderes kopieren. Mein erster Ansatz mit:
Delphi-Quellcode:
hat nicht funktioniert..
procedure TForm_liste.BtnSortClick(Sender: TObject);
var i, j: Integer; // ... dynArray1: array of TIrgendwas; dynArray2: array of TIrgendwas; begin SetLength(dynArray1, 200); //Länge des dynArray's SetLength(dynArray2, 200); //Länge des dynArray's // irgendwelche Werte werden dynArray1 zugewiesen ... FOR i := 1 TO high(dynArray1) DO begin dynArray2[i] := dynArray1[i]; end; habe dann gegooglet und die Funktion Copy(dynArray) gefunden:
Delphi-Quellcode:
wenn ich dann aber die beiden Arrays mit:
// Array kopieren
dynArray2 := Copy(dynArray1, 0, high(dynArray1));
Delphi-Quellcode:
vergleiche, dann steht beim letzten Element immer "text123 vs. [komische Zeichen]"
FOR i := 1 TO high(dynArray1) DO
begin ShowMessage(dynArray1[i].textinhalt + ' vs. ' + dynArray2[i].textinhalt); end; also scheinbar wird das letzte Element nicht kopiert ?! :?: hat jemand ein Tipp, was ich falsch mache? :wink: oder eine andere/bessere Möglichkeit dyn. Arrays zu kopieren? (aber muss eine richtige Kopie sein, nicht nur Reference) |
Re: dynamische Array kopieren (letztes Element fehlt)
dynamische Arrays beginnen immer bei 0. Ein dynamisches Array mit 3 Elementen geht also von yourarray[0] bis yourarray[2]
[Edit] Herzlich Willkommen in der Delphi-Praxis :dp: |
Re: dynamische Array kopieren (letztes Element fehlt)
(hatte oben noch einen kleinen Fehler drin bei der ersten FOR-Schleife)
Zitat:
Zitat:
also im Prinzip wird bei mir oben doch nur überall das erste Element (yourarray[0]) übersprungen? bzw. bleibt leer das erlkärt noch nicht das Fehlen des letzten Element ,oder? :?: |
Re: dynamische Array kopieren (letztes Element fehlt)
Es gibt zwar eine Refferenzzählung bei dynamischen Arrays, welche manchmal ihre Probleme hat.
Sonst würde man mit Folgendem keine Probleme haben.
Delphi-Quellcode:
Vorallem wird "leider" nicht vor dem Zuweisen eines Wertes geprüft, ob es eine Singleinstanz ist und somit werden die Werte direkt und somit auch aller gleichen Instanzen geändert.
dynArray2 := dynArray1;
Delphi-Quellcode:
sorgt dafür, daß es danach eine Einzelinstanz ist.
dynArray2 := Copy(dynArray1);
Sowas wie UniqueString gibt es leider nur für Strings (welche allerdings auch "nur" 'ne Sonderform von dynamischen Char-Arrays sind. |
Re: dynamische Array kopieren (letztes Element fehlt)
Delphi-Quellcode:
dann bekomme ich die folgende Fehlermeldung:
dynArray2 := dynArray1;
Zitat:
Delphi-Quellcode:
procedure TForm_liste.BtnSortClick(Sender: TObject);
var i, j: Integer; // ... dynArray1: array of TIrgendwas; dynArray2: array of TIrgendwas; begin |
Re: dynamische Array kopieren (letztes Element fehlt)
Nein, sind sie nicht.
Delphi-Quellcode:
Jetzt sind sie vom gleichen Typ.
type
TMyDynArray = array of Integer; var dynarray1: TMyDynArray; dynarray2: TMyDynArray; |
Re: dynamische Array kopieren (letztes Element fehlt)
Delphi ist da sehr strikt und es sind zwar ähnliche, aber nicht die selben Typen.
Delphi-Quellcode:
var dynArray1, dynArray2: array of TIrgendwas;
Delphi-Quellcode:
type TIrgendwasArray = array of TIrgendwas;
var dynArray1, dynArray2: TIrgendwasArray;
Delphi-Quellcode:
type TIrgendwasArray = array of TIrgendwas;
var dynArray1: TIrgendwasArray; dynArray2: TIrgendwasArray; |
Re: dynamische Array kopieren (letztes Element fehlt)
Der Befehl copy kopiert meines Wissens nicht von x bis y sondern ab x soundsoviel Elemente. Also müsste es
Delphi-Quellcode:
lauten, damit alle Elemente kopiert werden, oder?
dynArray2 := Copy(dynArray1, 0, Length(dynArray1));
|
Re: dynamische Array kopieren (letztes Element fehlt)
Nicht Length()-1?
|
Re: dynamische Array kopieren (letztes Element fehlt)
Zitat:
aber selbst wenn ich High(...)+1 nehme (was ja dann das selbe wie Length(...) ist, fehlt das letzte Element ----- ich dachte immer, dass das: var dynArray1, dynArray2: TIrgendwasArray; das selbe wie das ist: dynArray1: array of TIrgendwas; dynArray2: array of TIrgendwas; :o okay wenn ich jetzt
Delphi-Quellcode:
benutze, sind alle dynArrayX[i].textinhalt aufeinmal leer? :?
dynArray2 := dynArray1;
Edit: hmm habe 1 und 2 verwechselt .. okay danke es klappt :thumb: |
Re: dynamische Array kopieren (letztes Element fehlt)
Length(arr)-1 = High(arr) ... bei einem dynamischem Array
Und jupp, es ist Copy(source, start, len). Zitat:
|
Re: dynamische Array kopieren (letztes Element fehlt)
edit
|
Re: dynamische Array kopieren (letztes Element fehlt)
Man iteriert über alle eingebauten Delphi-Arrays, egal ob statisch, dynamisch, offen oder sonstwie, per
Delphi-Quellcode:
, und schon passt's.
Low(arr) to High(arr)
|
Re: dynamische Array kopieren (letztes Element fehlt)
Zitat:
Delphi-Quellcode:
:angel2:
//var el: telement;
// arr: array of telement; for el in arr do |
Re: dynamische Array kopieren (letztes Element fehlt)
Zitat:
Leider ist das for-in manchmal nicht gerade effizient, wenn man es mit "herkömmlichen" for-Schleifen vergleicht. Bei Schleifen über Sets und Arrays ist das aber WIMRE nicht so. Muss ich glatt bei Gelegenheit noch mal checken. |
Re: dynamische Array kopieren (letztes Element fehlt)
Mit
Delphi-Quellcode:
wird aber nur die Referenz kopiert. Wenn man nun
dynArray2 := dynArray1;
Delphi-Quellcode:
setzt, wird auch dynArray1[0] geändert! (Anderes als bei Strings). Das Kopieren der Referenz ist nicht das gleiche, wie der Copy-Befehl. Nur beim Copy-Befehl wird der komplette Inhalt kopiert.
dynArray2[0] := IrgendwasNeues;
Die Delphi-Hilfe dazu: Zitat:
|
Re: dynamische Array kopieren (letztes Element fehlt)
Zitat:
Edit: ich weiß nicht, wo der Fehler war.. aber jetzt funktioniert es auf einmal mit
Delphi-Quellcode:
:gruebel: (danke allen) :thumb:
dynArray2 := Copy(dynArray1, 0, High(dynArray1) + 1);
|
Re: dynamische Array kopieren (letztes Element fehlt)
Zitat:
Edit: ich weiß nicht, wo der Fehler war.. aber jetzt funktioniert es auf einmal mit
Delphi-Quellcode:
:gruebel: (danke allen) :thumb:[/quote]
dynArray2 := Copy(dynArray1, 0, High(dynArray1) + 1);
Delphi-Quellcode:
oder eben
dynArray2 := Copy(dynArray1, 0, Length(dynArray1));
Delphi-Quellcode:
dynArray2 := Copy(dynArray1);
|
AW: dynamische Array kopieren (letztes Element fehlt)
Nur mal so am rande bedeutet das, dass folgendes das selbe macht
Delphi-Quellcode:
Procedure Main;
var Keys:TStringDynArray; Procedure KeyFooRef(var arr:TStringDynArray)//MIT VAR Begin Setlength(arr,4); arr[0] := 'Das'; arr[1] := 'ist'; arr[2] := 'ein'; arr[3] := 'Test'; end; Procedure KeyFooVal(arr:TStringDynArray)// OHNE VAR Begin Setlength(arr,4); arr[0] := 'Das'; arr[1] := 'ist'; arr[2] := 'ein'; arr[3] := 'Test'; end; Begin KeyFooRef(Keys);//Fall 1 KeyFooVal(Keys);//Fall 2 end; |
AW: dynamische Array kopieren (letztes Element fehlt)
Zitat:
So sieht man's vielleicht deutlicher:
Delphi-Quellcode:
procedure Main;
var Keys: TStringDynArray; procedure KeyFooRef(var arr: TStringDynArray); //MIT VAR begin Setlength(arr, 4); arr[0] := 'Das'; arr[1] := 'ist'; arr[2] := 'ein'; arr[3] := 'Test'; end; procedure KeyFooVal(arr: TStringDynArray); // OHNE VAR begin Setlength(arr, 4); arr[0] := 'Das'; arr[1] := 'ist'; arr[2] := 'ein'; arr[3] := 'Test'; end; procedure Raus(AIndex: Integer; const arr: TStringDynArray); var i: Integer; begin Write(AIndex, ':'); for i := Low(arr) to High(arr) do Write(' ', arr[i]); Writeln; end; begin Raus(1, Keys); KeyFooRef(Keys); //Fall 1 Raus(2, Keys); Keys := nil; Raus(3, Keys); KeyFooVal(Keys); //Fall 2 Raus(4, Keys); end; |
AW: dynamische Array kopieren (letztes Element fehlt)
Weils hier öfters ein Problem war:
![]() |
AW: dynamische Array kopieren (letztes Element fehlt)
Ihr müsst bei "ohne var" das SetLength weglassen,
denn Dieses behandelt ordnungsgemäß die Referenzzählung und macht vor dem nachfolgenden Schreibzugriff die lokale "Kopie" unique. Mit "const" würde die Referenz nicht hochgezählt, was bei SetLength dann durchrutschen würde (wenn vor Funktionsaufruf nur eine Referenz existierte), aber da SetLength bei einer Kostante vom Compiler verweigert wird, gibt es dieses Problem dort nicht. Grund: außer bei LongStrings funktioniert für keine dynamischen Array die Referenzprüfung, wenn auf Felder schreibend zugegriffen wird. CopyOnWrite ist da nur für LongStrings (String, AnsiString, UnicodeString usw.) implementiert und fehlt seit Jahrzehnten. PS:
Delphi-Quellcode:
und übergabe an Parameter/Property erhöht nur den Referenzzähler.
A2 := A1;
Delphi-Quellcode:
, SetLength oder die UniqueXyz-Funktionen aus der System-Unit sollte man also vor Schreibzugriffen immer manuell aufrufen, wenn man mit "externen" Arrays arbeitet und deren Inhalt nicht veränder darf.
A2 := Copy(A2);
PSS: Noch ein Beispiel, dass auch LongStrings nicht von Problemen verschont werden.
Delphi-Quellcode:
function MeineFunktion: string;
begin Result := Result + 'X'; end; S := ''; for i := 1 to 10 do S := MeineFunktion; ShowMessage(S); |
AW: dynamische Array kopieren (letztes Element fehlt)
Bitte sagt mir ob ich das richtig verstanden habe!
Also wird tatsächlich immer eine Referenz auf ein DynArray übergeben. Abhängig von dem was ich danach mit der Referenz des Dnyarray mache wird unterschiedlicher Maschinencode erzeugt. Im
Code:
Fall, wird erst beim schreiben durch "Copy on Write" eine Arbeitskopie angelegt.
procedure KeyFooVal(arr: TStringDynArray)
Wenn ich nur lesend auf das Dynarray zugreife dann lese ich vom referenzierten Original? Das Schreiben auf Elementen des DynArray gilt nicht als Schreibenderzugriff auf das DynArray. "Copy on Write" erfolgt nicht. SetLength gilt als Schreiben auf das DynArray "copy on Write" erfolgt. Im
Code:
Fall, wird auch eine Referenz übergeben aber in keinem Fall erfolgt ein "Copy on write" wenn das DynArray bearbeitet wird.
procedure KeyFooRef(var arr: TStringDynArray);
>"This is madness!" |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:25 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