AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Wie kann man Informationen eines Arrays ermitteln?
Thema durchsuchen
Ansicht
Themen-Optionen

Wie kann man Informationen eines Arrays ermitteln?

Ein Thema von KodeZwerg · begonnen am 10. Sep 2022 · letzter Beitrag vom 10. Sep 2022
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#1

Wie kann man Informationen eines Arrays ermitteln?

  Alt 10. Sep 2022, 10:28
Wie kann man Informationen eines Arrays ermitteln?
Was ich gerne hätte wäre eine Möglichkeit unter (altem und neuem) Delphi und unter FreePascal, also mit primitiven Bordmitteln die in allen Pascal's vorhanden sein sollten, Dinge über ein Array zu erfahren.
Im Endeffekt interessiert mich nur die tatsächliche Größe des Array im Speicher, aber vielleicht gibt es ja auch noch Möglichkeiten die mir mehr Informationen darüber ausspucken, wie zum Beispiel wieviel Dimensionen es hat, wieviel Elemente pro Dimension vorhanden sind etc...

Hat da jemand Erfahrung mit und kann mir dabei bitte weiter helfen?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
type
  ArrayOfArrayOfDouble = array of array of double;
var
  Input: ArrayOfArrayOfDouble;
  i: Integer;
  size: Integer;
begin
  Randomize;
  SetLength(Input, 4);
  SetLength(Input[0], 2);
  SetLength(Input[1], 4);
  SetLength(Input[2], 6);
  SetLength(Input[3], 8);
  for i := Low(Input[0]) to High(Input[0]) do
    Input[0][i] := (Random(999) + 333) / (Random(9) + 3);
  for i := Low(Input[1]) to High(Input[1]) do
    Input[1][i] := (Random(999) + 333) / (Random(9) + 3);
  for i := Low(Input[2]) to High(Input[2]) do
    Input[2][i] := (Random(999) + 333) / (Random(9) + 3);
  for i := Low(Input[3]) to High(Input[3]) do
    Input[3][i] := (Random(999) + 333) / (Random(9) + 3);
  // macht man das so?
  size := 0;
  size := size + ((Length(Input[0]) * SizeOf(Input) + SizeOf(double)));
  size := size + ((Length(Input[1]) * SizeOf(Input) + SizeOf(double)));
  size := size + ((Length(Input[2]) * SizeOf(Input) + SizeOf(double)));
  size := size + ((Length(Input[3]) * SizeOf(Input) + SizeOf(double)));
end;
Ein Length() gibt mir ja nur die Elemente der ersten Ebene wieder.
Ein SizeOf() gibt mir nur die Größe des Pointers der Variable wieder.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#2

AW: Wie kann man Informationen eines Arrays ermitteln?

  Alt 10. Sep 2022, 11:19
Hallo KodeZwerg,
die jeweiligen Längen der einzelnen Dimensionen eines mehrdimensionalen Arrays (= Matrix) kann man so abfragen:
Delphi-Quellcode:
Zeilen := Length(Matrix); {1. Dimension}
Spalten := Length(Matrix[0]); {2. Dimension}
...
Grüße, Andreas
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#3

AW: Wie kann man Informationen eines Arrays ermitteln?

  Alt 10. Sep 2022, 11:52
die jeweiligen Längen der einzelnen Dimensionen eines mehrdimensionalen Arrays (= Matrix) kann man so abfragen:
Delphi-Quellcode:
Zeilen := Length(Matrix); {1. Dimension}
Spalten := Length(Matrix[0]); {2. Dimension}
...
Wobei der Wert für jedes Subarray unterschiedlich sein kann. Z.B. kann Matrix[1] eine andere Länge haben als Matrix[0] .

Folgendes gilt für Delphi:
Bei einem statischen Array kann man die Anzahl der Dimensionen und auch die Länge jeder Dimension über TypeInfo direkt ermittelt werden. Bei dynamischen Arrays muss das iterativ geschehen und da gibt es auch keine Längeninformation (ist halt dynamisch).

Delphi-Quellcode:
uses
  System.TypInfo;

type
  ArrayOfArrayOfDouble = array of array of double;
var
  cnt: Integer;
  I: Integer;
  Input: ArrayOfArrayOfDouble;
  size: Cardinal;
  ti: PTypeInfo;
  td: PTypeData;
begin
  ti := TypeInfo(ArrayOfArrayOfDouble);
  if ti.Kind = tkDynArray then begin
    td := ti.TypeData;
    if (td.elType <> nil) and (td.elType^.Kind = tkDynArray) then begin
      cnt := 0;
      for I := 0 to Length(Input) - 1 do
        Inc(cnt, Length(Input[I]));
      size := cnt * td.elType^.TypeData.elSize;
    end
    else begin
      size := Length(Input) * td.elSize;
    end;
  end;
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#4

AW: Wie kann man Informationen eines Arrays ermitteln?

  Alt 10. Sep 2022, 13:25
Uwe’s Lösung ist exzellent , kann aber auf den ersten Blick nur von Profis verstanden werden.
Bisher habe ich meine variablen Matrixdimsionen folgendermaßen gelöst:
Delphi-Quellcode:
n_Zeilen := Length(Matrix); {1. Dimension}
n_Spalten:= Length(Matrix[0]); {2. Dimension}
n_3D := Length(Matrix [0][0]); {3. Dimension}
n_4D := Length(Matrix [0][0][0]); {4. Dimension}

// Beispiel für 2 Dimensionen:
  For Zeile:= 0 To n_Zeilen - 1 Do
  Begin
    n_Spalten:= Length(Matrix[Zeile]); // Zeilenlängen könnten variieren
    For Spalte:= 0 To n_Spalten - 1 Do
    Begin
     ...
    End;
Bisher hat es stets funktioniert. Nennen wir das die Amateur-Variante...
Grüße, Andreas
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)

Geändert von Andreas13 (10. Sep 2022 um 13:44 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Wie kann man Informationen eines Arrays ermitteln?

  Alt 10. Sep 2022, 13:55
@Uwe, exzellent! Vielen Dank!! Jetzt wirds kniffelig wie ich das ganze in FPC hinbekomme

@Andreas, mir ging es nicht um "Length", mir geht es um die Größe wenn man das ganze zum Beispiel auf Festplatte sichern möchte oder in einem Stream schreiben etc, da brauch ich die Größe in Byte, aber vielleicht habe ich etwas übersehen, vielen Dank!
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.453 Beiträge
 
Delphi 12 Athens
 
#6

AW: Wie kann man Informationen eines Arrays ermitteln?

  Alt 10. Sep 2022, 15:10
Mein Code benötigt sowohl die Variable als auch den Typ. Eigentlich sollte damit schon gesamte Array-Struktur bekannt sein und der Zugriff auf TypeInfo wäre überflüssig.
Delphi-Quellcode:
type
  ArrayOfArrayOfDouble = array of array of double;
var
  cnt: Integer;
  I: Integer;
  Input: ArrayOfArrayOfDouble;
  size: Cardinal;
begin
  cnt := 0;
  for I := 0 to Length(Input) - 1 do
    Inc(cnt, Length(Input[I]));
  size := cnt * SizeOf(Double);
end;
Mit den Delphi Generics gäbe das schon mehr Sinn, aber dann wird's vermutlich nichts mit älteren Delphis und FPC. (Dann hätte ich meinen Code auch etwas anders formuliert)
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#7

AW: Wie kann man Informationen eines Arrays ermitteln?

  Alt 10. Sep 2022, 16:22
Jupp, die einfachen/alten RTTI TypeInfo-Dinge sollte FPC vom Delphi 1:1 kopiert haben und somit ginge der Code überall.

Ansonsten einfach mal in der System.pas bissl was abgucken, wie z.B. _DynArrayCopy.



Nicht vergessen SizeOf(TDynArrayTypeInfo) dazuzurechnen, wenn Length(arr)<>0 bzw arr<>nil .
Vor dem ersten Element liegen noch Verwaltungsdaten im RAM.
Aber dann fehlt auch noch der Speicher dahinter, also der ungenutzte Teil durch's MemoryAlignment.
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Wie kann man Informationen eines Arrays ermitteln?

  Alt 10. Sep 2022, 16:54
@Uwe, ach mein Held lass Dich mal drücken Vielen Dank!

@Himitsu, ich vermute Du meinst zum Ergebnis einmal SizeOf(Input) hinzu addieren. Padding sollte doch wegen "I * SizeOf(Type)" bereits drinnen sein, oder aber ich hab Dich da falsch verstanden. Vielen Dank!
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
701 Beiträge
 
Delphi 12 Athens
 
#9

AW: Wie kann man Informationen eines Arrays ermitteln?

  Alt 10. Sep 2022, 17:09
@Uwe, exzellent! Vielen Dank!! Jetzt wirds kniffelig wie ich das ganze in FPC hinbekomme

@Andreas, mir ging es nicht um "Length", mir geht es um die Größe wenn man das ganze zum Beispiel auf Festplatte sichern möchte oder in einem Stream schreiben etc, da brauch ich die Größe in Byte, aber vielleicht habe ich etwas übersehen, vielen Dank!
Einen dynamischen Array mit mehr als einer Dimension kann man nicht en bloc in ein File/Stream etc. speichern, da der Inhalt halt nicht in einem zusammenhängenden Memory-Block abgelegt ist! Beispiel:

Delphi-Quellcode:
type
  T3DArray = array of array of array of double;
var
  L3DArray: T3DArray;

SetLength(L3DArray, 3,3,3);
L3DArray enthält einen Pointer, der auf einen array von 3 pointern zeigt, von denen jeder auf einen weiteren array von 3 pointern zeigt. Erst diese zeigen dann jeweils auf einen array von 3 double-Werten.
Peter Below
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#10

AW: Wie kann man Informationen eines Arrays ermitteln?

  Alt 10. Sep 2022, 17:18
bei statischen Arrays geht es.

T = array[x..y] of array[x..y] of array[x..y] of double;

SizeOf(T) ist "dort" Alles.




Nein, SizeOf(Input) ist die Größe der Variable, welche auf das Array zeigt.
Und das sind immer 4 Byte, bzw. 8 Byte bei 64 Bit, da es einem SizeOf(Pointer) entspricht.

"IN" dem Array liegen aber vor dem Pointer, also vor dem ersten ArrayFeld @Input[0], noch die Verwaltungsdaten, welche TypInfo, Length und mehr enthalten (nur bei Length=0 gibt es das nicht), da Dieses z.B. für Copy und am Ende auch das FreeMem der Variable benötigt werden.

* für Größe der Daten in den Arrays, ist das unwichtig
* aber für Gesamtspeicher im RAM belegt es natürlich auch etwas
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (10. Sep 2022 um 17:23 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:56 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