Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Konstanter dynamischer Array <- Möglich? (https://www.delphipraxis.net/130572-konstanter-dynamischer-array-moeglich.html)

SebE 10. Mär 2009 21:10


Konstanter dynamischer Array <- Möglich?
 
Delphi-Quellcode:
type
  rec = record
    irgendwas: CHAR;
    liste: array of integer;
    end;

const
  A: array[0..1] of rec = (
    (irgendwas: 'a'; liste: (1, 2, 3, 5, 0)), <- hier mag Delphi meine Syntax nicht
    (irgendwas: 't'; liste: (3, 5, 90))
    );
Problem: Es sieht so aus, als kann man keine konstanten dynamischen arrays erstellen (lassen).

Kann nicht der Compiler die Längen ausrechnen?
Da es unter Umständen größere Datenmengen werden können, möchte ich versuchen, dass es so weit wie möglich automatisiert läuft (ohne Längenanpassungen)

Wer echt der Hit, wenn mir jemand sagen könnte, ob es in Pascal/Delphi doch funktioniert!
Danke schon einmal dafür

Meflin 10. Mär 2009 21:15

Re: Konstanter dynamischer Array <- Möglich?
 
Nein, das geht auch nicht.

SebE 10. Mär 2009 21:18

Re: Konstanter dynamischer Array <- Möglich?
 
Klare Ansage!

Danke dir.

Meflin 10. Mär 2009 21:25

Re: Konstanter dynamischer Array <- Möglich?
 
Zitat:

Zitat von SebE
Klare Ansage!

Ich wünschte ich irre mich. Nützlich wärs nämlich ;)

R2009 11. Mär 2009 05:12

Re: Konstanter dynamischer Array <- Möglich?
 
Hi,

konstant und dynamisch sind doch eigentlich ein Wiederspruch in sich oder?
Erklär doch mal genauer was du erreichen willst!

Schönen Tag noch!

Satty67 11. Mär 2009 06:48

Re: Konstanter dynamischer Array <- Möglich?
 
Wieso Widerspruch, dynamisch Größe für Ableitungen, die aber mit konstanten Werten.

So sind meine Tabellen-Felder vorab gespeichert. Array mit dynamischer Anzahl Feld/Typ und dann die konstanten Arrays jeder Tabelle mit der individuellen Anzahl an Werten.

Würde der Konstrukt wie oben funktionieren, könnte ich noch Datenbank und Tabellenname mit in einem Record speichern.

himitsu 11. Mär 2009 09:29

Re: Konstanter dynamischer Array <- Möglich?
 
Du könntest höchsten die Unter-Arrays als einzelne Konstanten erstellen und müßtest diese dann in die große Konstante einbinden.

Einzehln geht nicht, da du ja eine Array-Größe in der Struktur angeben muß und dieses nicht für jede Subebene einzeln angegeben werden kann.


[add]
Möglich wäre auch noch die maximale Größe vorzugeben und den Rest aufzufüllen.
z.B. mit Nullen oder einem mich-gibt's-nicht-Wert und eventuell noch eine Längenangabe an den Anfang zu stellen.

sirius 11. Mär 2009 09:49

Re: Konstanter dynamischer Array <- Möglich?
 
*räusper*
Hätte eigentlich nicht gedacht, dass dies funktioniert :cyclops:
Delphi-Quellcode:
type
  rec = record
    irgendwas: CHAR;
    liste: array of integer;
    end;

const
  L1: array[0..4] of integer=(2, //erster Eintrag ist Referenzzähler
                              3, //zweiter Eintrag für die Länge des eigentlichen Arrays
                              3, 5, 90); //und hier der Inhalt des eigentlichen Arrays
  L2: array[0..6] of integer=(2, 5, 1, 2, 3, 5, 0); //same as L1
  A: array[0..1] of rec = (
    (irgendwas: 'a'; liste: @L1[2]), //Zeiger auf den ersten eigetlichen Wert des Arrays
    (irgendwas: 't'; liste: @L2[2])
    );

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;


var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i,j:Integer;
begin
  for i:=low(a) to high(a) do
  begin
    memo1.lines.add(a[i].irgendwas);
    for j:=low(a[i].liste) to high(a[i].liste) do
      memo1.lines.add(inttostr(a[i].liste[j]));
  end;
end;
Edit: Fast vermutet und hat sich beim Test bestätigt --> einen referenzzähler brauchen unsere Arrays auch. -1, wie bei constanten Strings funktioniert leider nicht, also nehme ich mal +1.
Edit2: Die Frage ist noch, wie man das simuliert, wenn man mal kein Integer-Array hat?

Edit3: Und wer es mal für andere Arrays sucht...hier mal am Beispiel Strings.
Problem ist dabei noch der Referenzzähler. Bei 1 gibt es am Ende des Projektes einen Runtime-Error. Naja...ob man das produktiv einsetzen sollte?
Delphi-Quellcode:
type
    rec = record
    irgendwas: CHAR;
    liste: array of string;
    end;

    THeader=record
      ref:Integer;
      length:Integer;
    end;

    TL1 =record
      Header:THeader;
      Content:array[0..2] of string;
    end;

    TL2 =record
      Header:THeader;
      Content:array[0..4] of string;
    end;


const
  L1: TL1=(Header:(ref: 2; length: 3);
           Content: ('A','B','C'));
  L2: TL2=(Header:(ref: 2; length: 5);
           Content: ('A','B','C','D','X'));
  A: array[0..1] of rec = (
    (irgendwas: 'a'; liste: @L1.Content),
    (irgendwas: 't'; liste: @L2.Content)
    );

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;




var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var i,j:Integer;
    test:rec;
begin
  for i:=low(a) to high(a) do
  begin
    memo1.lines.add(a[i].irgendwas);
    for j:=low(a[i].liste) to high(a[i].liste) do
      memo1.lines.add(a[i].liste[j]);
  end;

  memo1.lines.add('---');
  Test:=a[0];

  for i:=low(a) to high(a) do
  begin
    memo1.lines.add(a[i].irgendwas);
    for j:=low(a[i].liste) to high(a[i].liste) do
      memo1.lines.add(a[i].liste[j]);
  end;

  memo1.lines.add('---');
  memo1.lines.add(test.irgendwas);
  for j:=low(test.liste) to high(test.liste) do
    memo1.lines.add(test.liste[j]);
end;

himitsu 11. Mär 2009 10:32

Re: Konstanter dynamischer Array <- Möglich?
 
klar geht das ... schon seit D4 ... da mal gemacht so ähnlich gemacht hatte :angel:

Delphi-Quellcode:
const
  L1: record
    RefCount, Length: Integer;
    Data: array[0..4] of Irgendwas;
  end;

@L1.Data
[edit] ahhh, bist ja selbst schon draufgekommen :angel2:

[add]
nimm aber lieber einen RefCount von mindestens 2 ... nicht das es Probleme gibt, wenn du das simulierte ConstArray mal an eine andere Array-Variable übergibst.

sirius 11. Mär 2009 10:35

Re: Konstanter dynamischer Array <- Möglich?
 
Zitat:

Zitat von himitsu
klar geht das ... schon seit D4 ... da mal gemacht so ähnlich gemacht hatte :angel:

Das liegt wohl mindestens an den fehlenden dynamischen Arrays vor D4 :zwinker:

Edit:
Zitat:

[add]
nimm aber lieber einen RefCount von mindestens 2 ... nicht das es Probleme gibt, wenn du das simulierte ConstArray mal an eine andere Array-Variable übergibst.
Habsch do!
Edit2: Oder meinst du im Integer-Array? Da gabs aber keine Probleme. Ich ändere es gleich. Besser ist.

himitsu 11. Mär 2009 10:41

Re: Konstanter dynamischer Array <- Möglich?
 
nja, kann auch D7 gewesen sein :gruebel:

aber da hatte ich zumindestens in Assembler die per "DB daten" eingebaut und dann das gesammte Array (nicht nur die Unterarrays) daruf umgeleitet.

praktisch nachträglich einer leeren Array-Variable diese konstanten Daten zugewiesen

[add]
Zitat:

Habsch do!
Edit2: Oder meinst du im Integer-Array? Da gabs aber keine Probleme. Ich ändere es gleich. Besser ist.
jupp, im Integer Array

Nicht daß mal der MemoryManager unter unglücklichen Umständen ausversehn versucht die konstanten Daten, welche nicht hier ja in seinem Bereich liegen freizugeben.

Oder ausversehn in einem anderem Var-Array, welchem man vorher dieses Array übergeben hat, beim Ändern von Werten diese versucht werden in der Konstante zu ändern, statt vorher eine Kopie anzulegen.

Die Referenzzählung machte bei mir schonmal Probleme, als ich (nur bei normalen Array's und nicht expliziet bei soeinem Const-Array) versuchte den Wert zu ändern.

Delphi-Quellcode:
// nur daß hierbei auch Array1[x] geändert wurde
Array2 := Array1;
Array2[x] := irgendwas;

// hier ging es aber o.O
Array2 := Copy(Array1);
Array2[x] := irgendwas;

SebE 11. Mär 2009 12:51

Re: Konstanter dynamischer Array <- Möglich?
 
@sirius :
Dein Beispiel ist sehr interessant.
Wenn ich das richtig verstanden habe: Der Referenzzähler ist 2 -> einer für die Konstante selbst und der zweuite für die "Record-Zuweisung"

Meine Idee war Nullterminierte Arrays anzulegen.

Schön, dass sich dieser Thread selbstständig gemacht hat und man wieder etwas lernen konnte.

Edit: Warum legen dynamische Array keine Größen-/Referenz-Felder an?

sirius 11. Mär 2009 13:07

Re: Konstanter dynamischer Array <- Möglich?
 
Zitat:

Zitat von SebE
@sirius :
Dein Beispiel ist sehr interessant.
Wenn ich das richtig verstanden habe: Der Referenzzähler ist 2 -> einer für die Konstante selbst und der zweuite für die "Record-Zuweisung"

eigentlich müsster er -1 sein. Denn das bedeutet (zumindest bei Strings), dass das Array nie gelöscht wird. Darf es ja auch nicht, ist ja eine Konstante. Der Wert 1 wäre eigentlich "am richtigsten", aber hier gibt es Probleme aus noch nicht näher geklärten Gründen. Und es schadet ja nicht, den Zähler richtig hoch zu setzen.
Zitat:

Edit: Warum legen dynamische Array keine Größen-/Referenz-Felder an?
Machen Sie ja. Aber eben nur zur Laufzeit.

himitsu 11. Mär 2009 13:08

Re: Konstanter dynamischer Array <- Möglich?
 
Eigentlich ist die Referenz -1 (steht normaler Weise für "liegt nicht im RAM") .. bzw 1, wenn nur eine Refferenz vorhanden ist ... hier aber sicherheitshalber 2, damit es nicht unter blöden Umständen vorkommt, daß mal versucht wird den "nicht vorhandenen" Speicher freizugeben oder darin rumzuschreiben.


Delphi-Quellcode:
Type TDynArray = packed Record
    RefCount:    LongInt;
    ElementCount: LongInt;
    Data:        packed Array[0..High({var})] of {Typ};
  End;

Var var: TMyDynArray;

var = @TDynArray.Data; // die Variable zeigt auf den Anfang von Data

// Pointer(var)    = nil    > nil {in EXE}     > nil {in RAM}
//
// RefCount        = 0       = -1               > 0
// ElementCount    = 0       = Length(var)     = Length(var)
// @Data           -         = var             = var
also man kann (zumindestens bei Strings, welche im Grunde auch nur ein dynamisches Array darstellen)
aus dem Pointer rausbekommen, ob es Inhalt gibt oder der String '' ist
und aus RefCount bekommt man mit wo der String liegt (-1 = Konstante, 0 gibt's nicht und größer 0 gibt es die Anzahl der Referenzen an)

PS: Beim alten Delphi-MemoryManager lag vor RefCount noch dein weiter Integer vom SpeicherManager (welcher Status des Speicherblocks angab)


[add]
Zitat:

Zitat von SebE
Edit: Warum legen dynamische Array keine Größen-/Referenz-Felder an?

bei statischen Array's ist das anders angelegt.
da gibt es keine Referenzzählung und auch die Arraygröße ist nicht in die Datein eingebaut.

dieses sieht praktisch so aus:
Delphi-Quellcode:
Type TStaticArray = packed Record
    Data: packed Array[0..High({var})] of {Typ};
  End;
Length(array) und High(array) werden dabei direkt in das Programm eingebaut.
(die Länge kennt der Compiler ja und baut dann da wo diese Funktionen aufgerufen würden direkt die entsprechende Zahl ein)

SebE 11. Mär 2009 13:15

Re: Konstanter dynamischer Array <- Möglich?
 
Super, danke euch.

Ist es eine "reine" Delphi-Angewohnheit oder machen es andere (imperative) Sprachen (wie C) auch so?

Wo habt ihr eurer genaues Wissen her (Delphi-Tutorials, oder zählt das unter "allgemein", so dass man das im Theorieteil eines Informatik-Buches nachlesen kann)?

sirius 11. Mär 2009 13:19

Re: Konstanter dynamischer Array <- Möglich?
 
Das ist delphispezifisch. Gerade so eine "tolle" :zwinker: Sprache wie C hat diese tolle Verwaltung von Strings nicht. Ähnlich sieht es mit dynamischen Arrays aus.
Hier hat der Delphi-Compiler im Hintergrund auch ganz schön zu tun.

Wo man das Wissen herbekommt?
Mitlesen in dem Forum und Rumprobieren und Angucken des CPU-Fensters....

himitsu 11. Mär 2009 13:20

Re: Konstanter dynamischer Array <- Möglich?
 
Liste der Anhänge anzeigen (Anzahl: 1)
[info] hatte oben noch was zum StaticArray nacheditiert.

und rausbekommen hatte ich es, indem ich einfach mal Speicher mir angeguckt hatte :roll:

PS: bei WideString (OLE32Str) ist der ElementZähler in Byte angegeben, also immer doppelt so groß wie die Zeichenanzahl.
und es gibt keine Referenzzählung (bzw. die ist immer 1)

[add]
schau dir einfach mal im Anhang die Funktionen DynArrayInfo/DynArrayInfoC bzw. StringInfo/StringInfoC an

sirius 11. Mär 2009 13:29

Re: Konstanter dynamischer Array <- Möglich?
 
Zitat:

Zitat von himitsu
PS: bei WideString (OLE32Str) ist der ElementZähler in Byte angegeben, also immer doppelt so groß wie die Zeichenanzahl.

Widestring ist ja auch von Windows implementiert. Da werden intern nur die API-Funktion StrAlloc, StrLen,.... StrDispose aufgerufen.
Und eine neue Variable bekommt auch immer eine Kopie und niemals eine zweite Referenz auf einen Widestring. Dafür gibts ja jetzt UnicodeStrings :D

SebE 11. Mär 2009 13:36

Re: Konstanter dynamischer Array <- Möglich?
 
Zitat:

bei WideString (OLE32Str) ist der ElementZähler in Byte angegeben, also immer doppelt so groß wie die Zeichenanzahl.
Wie soll ich das verstehen?
Ein Element (ein Zeichen) ist doch immer ein Byte(?)

himitsu 11. Mär 2009 14:03

Re: Konstanter dynamischer Array <- Möglich?
 
WideString = WideChar = 2 Byte pro Zeichen

UnicodeString (gibt es seit D2009) = WideChar = auch 2 Byte pro Zeichen,
aber hier gibt ElementCount die anzahl der Elemente/Zeichen an,
so wie eigentlich bei allen Delphi-Array's auch.
(OK Ansi = 1 Byte pro Zeichen, also da stimmt es überein)

Der Grund: WideString ist nur eine delphiinterne Umleitung zum OLEString und der zählt halt anders.

SebE 11. Mär 2009 14:07

Re: Konstanter dynamischer Array <- Möglich?
 
So viel Neues...echt interessant.

Ich beschäftige mich im Moment mit dem Thema Compilerbau.
Da sind solche Informationen echt wichtig, wenn ich bei der Speicherverwaltung und zur Laufzeitverwaltung komme (mach alles von Hand, deshalb bin ich für jede neue Info dankbar, auch für Alternativen zB eine andere Art Array/Records darzustellen (deshalb meine Frage mit dem Informatik-Buch))


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