Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Problem beim Kopieren von dyn. Arrays (https://www.delphipraxis.net/71975-problem-beim-kopieren-von-dyn-arrays.html)

Stefan Hueg 23. Jun 2006 03:31


Problem beim Kopieren von dyn. Arrays
 
Ich habe hier nun ein Problem wo ich echt nicht weiterkomme.

Ich habe folgende Situation:

-Unit des Hauptformulars hat folgendes im Interface-Teil deklariert

Delphi-Quellcode:
type
  TZeitserver = record
    IP: String;
    LastPing: String;
    LastCheck: String;
  end;

var
  Zeitserver: array of TZeitserver;
Soweit sogut. Ein dynamisches Array, in welches dann weiter in der Unit Daten auch eingelesen werden. Das funktioniert auch.
Nun habe ich eine zweite Unit in welcher ich eine Kopie des Arrays aus der ersten Unit benötige.

Erstes Problem:
-Wie kriege ich die Typendefinition aus Unit1 in Unit2?

Meine Lösung:
-Einfach das gleiche nochmal in den Interface-Teil aus der ersten in die Zweite Unit kopieren (type TZeitserver = record etc...)

Das Problem
-Er meldet incompatible types. Kopiert wird das ganze mit

Delphi-Quellcode:
    TempZeitserver := Copy(frmMain.Zeitserver, 0, Length(frmMain.Zeitserver));
Wie geht das?

Flare 23. Jun 2006 05:37

Re: Problem beim Kopieren von dyn. Arrays
 
Also einbinden kannst du die unit1, indem du einfach in unit2 diese in die uses-Liste schreibst (im Implementation-Teil).
Delphi-Quellcode:
implementation

uses unit1;

{$R *.dfm}
Zum kopieren von diesem Array kann ich nix sagen, da ich das selber noch nie gemacht habe.


Flare

Dust Signs 23. Jun 2006 08:42

Re: Problem beim Kopieren von dyn. Arrays
 
Zitat:

Zitat von Stefan Hueg
Delphi-Quellcode:
    TempZeitserver := Copy(frmMain.Zeitserver, 0, Length(frmMain.Zeitserver));

Wenn TempZeitServer vom Typ TZeitServer ist, kann diese Zuweisung auch nicht funktionieren. Du weist einem TZeitServer einen String zu... du kannst höchstens einem der Felder des Zeitservers einen String zuweisen.

Dust Signs

Sascha L 23. Jun 2006 08:49

Re: Problem beim Kopieren von dyn. Arrays
 
Ich weiß jetzt nicht, ob es extra einen Befehlt dafür gibt, aber ansonsten mach es doch ganz einfach mit einer Schleife ;-)

Du ermittelst die Länge des 1. Arrays und setzt diese für den 2. Array. Über eine Schleife setzt du dann die Werte des 1. Arrays für den 2. Array.

Delphi-Quellcode:
SetLength(Array2,Length(Array1));

for i:=0 to Length(Array2)-1 do begin
  Array2[i].IP := Array1[i].IP;
  Array2[i].LastPing := Array1[i].LastPing;
 {...}
end;

Hawkeye219 23. Jun 2006 09:35

Re: Problem beim Kopieren von dyn. Arrays
 
Hallo Stefan,

die vom Compiler gelieferte Fehlermeldung ist verständlich, da du durch das Kopieren der Typdefinition einen neuen Typen erzeugst. Obwohl beide Typen den gleichen Aufbau besitzen, sieht der Compiler sie als unterschiedlich an. Gib deinem dynamischen Array einen Namen und lagere die Typdefinition in eine weitere Unit aus, die du dann in deinen beiden Units in die USES-Anweisung aufnimmst:

Delphi-Quellcode:
unit Typen;

interface

type
  TZeitserver = record
    IP: String;
    LastPing: String;
    LastCheck: String;
  end;

  TDynZeitserverArray = array of TZeitserver;
 
implementation

end.
Das Kopieren von Arrays kannst du - wie von Dust Signs beschrieben - mit dem Copy-Befehl durchführen. Start und Länge mußt du dabei nicht angeben:

Delphi-Quellcode:
var
  Original, Kopie : TDynZeitserverArray;
begin
  Kopie := Copy(Original);
end;
Eine einfache Zuweisung der Zeiger würde lediglich den Referenzzähler des Original-Arrays erhöhen. Danach wäre jede Änderung, die du mit einem der beiden Arrrays durchführst, auch im jeweils anderen sichtbar.

Gruß Hawkeye

Stefan Hueg 23. Jun 2006 12:47

Re: Problem beim Kopieren von dyn. Arrays
 
Achso alles klar, werde ich mal ausprobieren. Die Länge und den Index beim Copy Befehl hatte ich eingegeben da ich durch die Suche einen ähnlichen Beitrag gefunden hatte in dem gesagt wurde dass Länge und Index angegeben werden müssten

himitsu 23. Jun 2006 12:57

Re: Problem beim Kopieren von dyn. Arrays
 
Zitat:

Zitat von Hawkeye219
Eine einfache Zuweisung der Zeiger würde lediglich den Referenzzähler des Original-Arrays erhöhen. Danach wäre jede Änderung, die du mit einem der beiden Arrrays durchführst, auch im jeweils anderen sichtbar.

Das ist schon richtig (dat mit dem Referenzzähler), aber sobald man was ändert, wird dennoch eine eigene Kopie angelegt (beim ändern wird der Refferenzzähler halt immer erst auf 1 gesetzt, also notfalls eine eigene Kopie angelegt), so daß Änderungen nicht in jeder Refferenz sichtbar sind.

Hawkeye219 23. Jun 2006 13:06

Re: Problem beim Kopieren von dyn. Arrays
 
@himitsu
Hast du es schon einmal ausprobiert?

Zitat:

Zitat von Delphi-Hilfe
Wenn X und Y Variablen desselben dynamischen Array-Typs sind, führt die Anweisung X := Y dazu, daß X auf dasselbe Array wie Y zeigt (es ist nicht erforderlich, vor dieser Operation Speicher für X zu reservieren). Im Gegensatz zu Strings und statischen Arrays werden dynamische Arrays nämlich nicht automatisch kopiert, bevor einem ihrer Elemente ein Wert zugewiesen wird. Beispielsweise hat A[0] nach der Ausführung des folgenden Quelltextes den Wert 2:

Code:
var
  A, B: array of Integer;
begin
  SetLength(A, 1);
  A[0] := 1;
  B := A;
  B[0] := 2;
end;
Wenn A und B statische Arrays wären, hätte A[0] immer noch den Wert 1.

Gruß Hawkeye

himitsu 23. Jun 2006 13:21

Re: Problem beim Kopieren von dyn. Arrays
 
Strings (AnsiStrings) sind auch "nur" dynamische Arrays und im Gegensatz zu dem, was laut dem in der OH stehen soll, werden Strings auch kopiert, wenn man sie ändert, obwohl sie intern ebenfalls dynamische Arrays sind.

Und laut der offiziellen Definition dieser dynamsichen Typen mit Refferenzzählung sollte es jedenfalls so sein (wie ich geschrieben hab)?


Nein, getestet hatte ich es noch nicht, aber ich konnte bisher auch noch keinen Fehler entdecken, welcher darauf zu führen war, daß nicht kopiert wurde ... obwohl ich schon ein paar dynamische Arrays verwendet hab. :gruebel:


wie gesadt, Strings sind intern eigentlich genauso wie dynamische Arrays definiert (abgesehn, daß sie bei 1 beginnen und noch ein "unsichtbares", zusätzliches Feld mit dem Wert #0 am Ende haben) und dort funktioniert es doch aus o.O
Delphi-Quellcode:
var A, B: String;
begin
  SetLength(A, 1);
  A[1] := '1';
  B := A;
  B[1] := '2';
  // A[1] ist immernoch '1'
end;
Also wenn das Fettgedruckte stimmt, dann würde ich das als einen GROOOOOßEN, absichtlichen Delphi-Bug ansehen :evil:


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