![]() |
Merkwürdiges Problem mit einem dynamischen Array
Hallo,
wenn ich ein dynamisches Array global wir folgt deklarieren will:
Code:
Bekomme ich vom Compiler folgende Fehler ausgeworfen:
private
{ Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; var a:Array of Double; implementation 1. Fehler: [ erwartet, aber 'OF' gefunden 2. Fehler: 'OF' erwartet, aber 'implementation' gefunden Kopiere ich folgende Methoden aus der Delphi-Hilfe in den Quellcode, compiliert er ohne Fehler:
Code:
procedure Clear(var A: array of Double);
var I: Integer; begin for I := 0 to High(A) do A[I] := 0; end; function Sum(const A: array of Double): Double; var I: Integer; S: Double; begin S := 0; for I := 0 to High(A) do S := S + A[I]; Sum := S; end; Weiss jemand woran dieses Verhalten liegt? Was mache ich falsch? Meine Delphi-Version ist 3. Gruß Thomas |
Re: Merkwürdiges Problem mit einem dynamischen Array
Delphi 3 kann so weit ich das weiß keine dynamischen Arrays.
Delphi-Quellcode:
Grüße
private
{ Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; var a:Array [0..10] of Double; implementation Klaus |
Re: Merkwürdiges Problem mit einem dynamischen Array
Ich glaub Delphi 3 unterstützt noch gar keine dynamischen Arrays,
schlagt mich wenn ich falsch liege aber ich meine ich hätte dass mal gelesen! |
Re: Merkwürdiges Problem mit einem dynamischen Array
Nochmal anders formuliert: es ist ein Unterschied zwischen einer dynamischen Array-Variablen und einem offenen Array-Parameter.
Grüße vom marabu |
Re: Merkwürdiges Problem mit einem dynamischen Array
Worin lieg denn dieser?
Wie nutze ich Array-Variablen? Gruß Thomas |
Re: Merkwürdiges Problem mit einem dynamischen Array
Du erstellst die 'nen VorlageTypen
Delphi-Quellcode:
daraus wird dann der PointerTyp erstellt/genutzt
Type TMyDoubleArray = Array[0..0] of Double;
Delphi-Quellcode:
und dann mußt du für die Speicherresservierung (z.B. per GetMem/FreeMem/eallocMem) sorgen.
Type PMyDoubleArray = ^TMyDoubleArray;
Var MyDoubleVar: PMyDoubleArray; // oder Var MyDoubleVar: ^TMyDoubleArray;
Delphi-Quellcode:
MyDoubleVar := GetMem(x * SizeOf(Double));
|
Re: Merkwürdiges Problem mit einem dynamischen Array
Nach der Speicherreservierung kann ich das verpointete Array normal nutzen? Also über a[x]?
Gruß Thomas |
Re: Merkwürdiges Problem mit einem dynamischen Array
jop.
Setlength funktioniert dann natürlich nicht, zur Vergrößerung musst du wieder Speicher alloziieren. (wie geht denn das? den speicherbereich vergrößern? :gruebel: ) |
Re: Merkwürdiges Problem mit einem dynamischen Array
Vielen Dank!
Dann weiss ich bescheid! Gruß Thomas |
Re: Merkwürdiges Problem mit einem dynamischen Array
Zitat:
|
Re: Merkwürdiges Problem mit einem dynamischen Array
|
Re: Merkwürdiges Problem mit einem dynamischen Array
Ok
|
Re: Merkwürdiges Problem mit einem dynamischen Array
ReallocMem, oder Realloc, oder wie dat heißt ... siehe OH?
Delphi-Quellcode:
na ja, oder
Arr := ReallocMem(Arr, xNew * SizeOf(Double));
// oder so ... jenachdem, ob man da Arr als Var-Parameter übergeben kann ReallocMem(Arr, xNew * SizeOf(Double))
Delphi-Quellcode:
var Arr, Temp: TMyArray;
Temp := GetMem(xNew * SizeOf(Double)); Move(Arr, Temp, Min(x, xNew) * SizeOf(Double)); FreeMem(Arr); Arr := Temp; Aber es empfiehlt sich natürlich, wenn du irgendwo die Größe speicherst ... weil sowas wie Length(MyDoubleArray) geht natürlich och nicht :zwinker:
Delphi-Quellcode:
oder im Typen
Type TMyDoubleArray = Array[0..0] of Double;
PMyDoubleArray = ^MyDoubleArray; Var MyDoubleArraySize: Integer; MyDoubleArray: PMyDoubleArray;
Delphi-Quellcode:
Type TMyDoubleArray = Record
Size: Integer Data: Array[0..0] of Double; End; PMyDoubleArray = ^MyDoubleArray; Var MyDoubleArray: PMyDoubleArray; [add] zu langsam -.-'' |
Re: Merkwürdiges Problem mit einem dynamischen Array
In der Codelib sind auch Klassen dafür:
![]() |
Re: Merkwürdiges Problem mit einem dynamischen Array
Die dynamischen Arrays in der CodeLib sind aber auf einen bestimmten Type spezifiziert oder? Also Integer, Word oder Pointer...
Gruß Thomas |
Re: Merkwürdiges Problem mit einem dynamischen Array
Da Pointer aber auch nur Zeiger auf irgendeinen Speicher sind....
Du müsstest halt nur casten Gruß Der Unwissende |
Re: Merkwürdiges Problem mit einem dynamischen Array
Das heisst ich legen dann jeweils einen zeiger auf das Objekt, welches meine Daten enthält, oder?
Gruß Thomas |
Re: Merkwürdiges Problem mit einem dynamischen Array
Na ja, ein Zeiger muss nicht auf ein Objekt zeigen (sorry wenn ich mal so kleinlich bin). Wenn du Integer Werte speicherst, dann liegen die irgendwo im Speicher (kannst also auch einen Zeiger darauf speichern), das gilt auch für Bytes, Strings, ..., beliebige Klassen.
Ob es Sinn macht einen Zeiger zu speichern ist immer eine andere Sache. Dein Zeiger hat den Vorteil, dass er sehr universell ist. Zudem hat er immer die volle Registerbreite deines OS (i.d.R. also 4 Byte). Jetzt ist ein Byte aber nun mal nur ein Byte groß. Wenn du also Pointer auf das Byte speicherst... Von der Perfomance her wäre es natürlich an sich schlecht Byte zu verwenden (da müssen 3 Byte mit 0en gefüllt werden) und Platz hat man auf heutigen System offensichtlich genug (kenne wenig Programme die da an Speicher sparen, vorallem nicht bei solchen Variablen!) Wie gesagt, man könnte über den Sinn streiten. Wenn du ein Array von Pointern verwendest, kannst du so ziemlich alles speichern (eigentlich sogar genau alles). Dann solltest du aber schauen, wie gut die Umsetzung von TList in Delphi 3 ist (vielleicht gibt es dort ja schon eine TList). Diese ist nichts anderes als ein Array of Pointer, das geschickt von Delphi verwaltet wird. So alloziert eine TList automatisch Speicher und gibt ungenutzten auch wieder frei. Das beantragen und verändern der Speichergröße kostet unabhängig von der eigentlich Größe nahezu konstant viel Zeit. Würdest du also bei jedem neuen Element immer die Länge um 1 vergrößern wird das schnell recht aufwändig. Vergrößerst du das Array gleich um 100 Elemente, so sparst du max. 99 solcher Aufrufe. TList bietet den Vorteil sich genau darum selbst zu kümmern. Ich weiß wie gesagt nicht wie es da unter Delphi 3 aussieht. Was ein dynamisches Array angeht, du könntest mit einem Array of Pointer halt alles machen, aber du hast natürlich keine Typsicherheit mehr:
Code:
Dieser Code würde funktionieren und du hättest gleich mehrere Fallen. Einerseits siehst du, dass hier 3 unterschiedliche Typen in das Array gepackt wurden. Was sich an der Stelle a[0] befindet ist aber eine 32-Bitige (vielleicht auch schon 64) Adresse. Diese Adresse wird ungleich 0 sein (die Variablen gibt es ja zu dem Zeitpunkt alle und sie sind lokal). Das heißt beim auslesen des Arrays an Stelle 0 könntest du auch in ein Char oder eine TList casten. Ob das glückt ist eine andere Sache!
var a : Array of Pointer; // wie auch immer es dann in einer Delphi 3 Umsetzung aussähe!
b : Byte; i : Integer; c : Cardinal; o : TObject; begin setLength(a, 4); b := 0; i := -1; c := 4000000000; a[0] := @b; a[1] := @i; a[2] := @c; // noch eine Falle! a[3] := @o; end; Das andere Problem ist, du hast hier die Adressen lokaler Variablen stehen. Steht dies in einer Prozedur, würden die Adressen keine Gültigkeit nach dem Ende der Prozedur haben. Gut in diesem Fall wird auch das dynamische Array in dieser Prozedur angelegt, aber wenn es global wäre... Die Adressen behalten natürlich ihre Gültigkeit (es gibt die Adresse noch), was dort steht ist aber mit dem Ende der Prozedur eher zufällig. Hier kommt auch die weitere Falle ins Spiel. o ist ein TObject, wie du siehst wird der Konstruktor nie aufgerufen. Die gespeicherte Adresse a[3] kann aber <> nil sein. Dies liegt einfach daran, dass o lokal ist. Lokale Variablen (auch Pointer und Referenzen) sind nicht initialisiert. Diese Probleme können immer auftauchen, wenn du mit Pointern arbeitest. Deswegen macht man es ja so ungerne. Typsicherheit kann man natürlich leicht durch typisierte Pointer erreichen oder Kapselungen, die dir das einfügen nur von einem bestimmten Datentyp erlauben und aut. casten, wenn du lesend zugreifst. Gruß Der Unwissende |
Re: Merkwürdiges Problem mit einem dynamischen Array
Vielen Dank!
Jetzt komme ich denke ich klar ;-) Wenn ich noch mal Fragen habe poste ich wieder ... :-) Gruß Thomas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:47 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