![]() |
Konstanter dynamischer Array <- Möglich?
Delphi-Quellcode:
Problem: Es sieht so aus, als kann man keine konstanten dynamischen arrays erstellen (lassen).
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)) ); 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 |
Re: Konstanter dynamischer Array <- Möglich?
Nein, das geht auch nicht.
|
Re: Konstanter dynamischer Array <- Möglich?
Klare Ansage!
Danke dir. |
Re: Konstanter dynamischer Array <- Möglich?
Zitat:
|
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! |
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. |
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. |
Re: Konstanter dynamischer Array <- Möglich?
*räusper*
Hätte eigentlich nicht gedacht, dass dies funktioniert :cyclops:
Delphi-Quellcode:
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.
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; 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; |
Re: Konstanter dynamischer Array <- Möglich?
klar geht das ... schon seit D4 ... da mal gemacht so ähnlich gemacht hatte :angel:
Delphi-Quellcode:
[edit] ahhh, bist ja selbst schon draufgekommen :angel2:
const
L1: record RefCount, Length: Integer; Data: array[0..4] of Irgendwas; end; @L1.Data [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. |
Re: Konstanter dynamischer Array <- Möglich?
Zitat:
Edit: Zitat:
Edit2: Oder meinst du im Integer-Array? Da gabs aber keine Probleme. Ich ändere es gleich. Besser ist. |
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:
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; |
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? |
Re: Konstanter dynamischer Array <- Möglich?
Zitat:
Zitat:
|
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:
also man kann (zumindestens bei Strings, welche im Grunde auch nur ein dynamisches Array darstellen)
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 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:
da gibt es keine Referenzzählung und auch die Arraygröße ist nicht in die Datein eingebaut. dieses sieht praktisch so aus:
Delphi-Quellcode:
Length(array) und High(array) werden dabei direkt in das Programm eingebaut.
Type TStaticArray = packed Record
Data: packed Array[0..High({var})] of {Typ}; End; (die Länge kennt der Compiler ja und baut dann da wo diese Funktionen aufgerufen würden direkt die entsprechende Zahl ein) |
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)? |
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.... |
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 |
Re: Konstanter dynamischer Array <- Möglich?
Zitat:
Und eine neue Variable bekommt auch immer eine Kopie und niemals eine zweite Referenz auf einen Widestring. Dafür gibts ja jetzt UnicodeStrings :D |
Re: Konstanter dynamischer Array <- Möglich?
Zitat:
Ein Element (ein Zeichen) ist doch immer ein Byte(?) |
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. |
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 02:34 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