Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Zeiger auf dynamisches zweidimensionales Array


M.Mü - So 11.12.05 02:57
Titel: Zeiger auf dynamisches zweidimensionales Array
Hallo,

ich habe ein dynamisches zweidimensionales Array of Byte generiert und will nun über eine Zeigervariable auf den Inhalt zugreifen. Allerdings geht das nicht, wie ich mir das dachte.

Mein Programm in Bruchstücken:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
type TdynArray2dim = array of array of Byte;
var Z: TdynArray2dim;

...
...
...

procedure Initialisierung;
var i, j : byte;
begin
 SetLength(Z,3);

 for i := Low(Z) to High(Z) do
   SetLength(Z[i],4);

 for i := 0 to 2 do
  for j := 0 to 3 do
    Z[i][j] := StrToInt(IntToStr(i) + IntToStr(j));
end;

...
...
...

procedure Auslesen;
var PZ: ^byte;
    i,j: byte;
begin
 PZ := @Z;
 for i := 0 to 2 do
   for j := 0 to 3 do
     begin
       Memo3.Lines.Add(IntToStr(PZ^));
       inc(PZ);
     end;
end;


Es werden irgendwelche Werte aus dem Array gelesen, nur nicht die, die ich am Anfang geschrieben habe.

Warum? Bin ratlos ... Bildet das Array keinen einheitlichen Adressraum? Oder ist die Startadresse nicht @Z ? ...

M.Mü

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt


delfiphan - So 11.12.05 03:06

Probier's mal mit @Z[0,0] oder ähnlich.


M.Mü - So 11.12.05 03:40

Hab Dank für die Idee. Sie war von Erfolg gekrönt. Mein Programm sieht denn so aus


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure Auslesen;
var PZ: ^byte;
    i,j: byte;
begin
 PZ := @Z;
 for i := 0 to 2 do
   begin
     PZ := @Z[i][0];
     for j := 0 to 3 do
       begin
         Memo3.Lines.Add(IntToStr(PZ^));
         inc(PZ);
       end;
end;


Allerdings viel mir dabei auf, dass die Adressen im Speicher nicht zusammenhängend sind.

Z => $453C20
Z[0][0] => $8D20B0; Z[0][1] => $8D20B1; ... Z[0][3] => $8D20B3;
Z[1][0] => $8D20C0; Z[1][1] => $8D20C1, usw.
Z[2][0] => $8D20D0; Z[2][1] => $8D20D1, usw.

Kann Delphi da so uneffektiv sein? Oder gibts da einen bestimmten Grund? Hmmm ... schließlich ist es auch ein Array of Array und kein Array[0..2,0..3] ...

M.Mü


delfiphan - So 11.12.05 03:59

Das liegt daran, dass die Länge der Sub-Arrays veränderbar sind. Wenn die Grösse eines Sub-Arrays verändert wird, müsste man - wenn alles zusammenhängend wäre - das gesamte Array neu schreiben. Das wäre natürlich sehr ineffektiv.
Array of Array of ... muss man wörtlich verstehen. Es ist ein dynamisches Array von dynamischen Arrays. Jeder dieser dynamischen Arrays besteht aus einem Pointer zum ersten Element und der Gesamtlänge (und noch anderen internen Infos wie Referenzcounter). Diese Pointer zu den ersten Elementen sind unabhängig voneinander und nicht hintereinandergereiht.
Wenn dir die Performance wichtig ist, dann solltest du eindimensionale Arrays benützen und die Indizes von Hand umrechnen.


Kroko - So 11.12.05 13:26


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure Initialisierung;
var i, j : byte;
begin
 SetLength(Z,3,4); //geht auch!
...
end;


M.Mü - So 11.12.05 14:25

@delfiphan
Klingt einleuchtend. Hab vielen Dank. Ich werde dann wohl auf das eindimensionale Array zurückgreifen. Der Zugriff auf die einzelnen Zellen erfolgt ja auf ähnliche Weise ...

@Kroko
Danke für den Tipp.

Gruß M.Mü