0

I’m perfectly avare that pointer math in Delphi should be used with special care, but I still don’t get where am I wrong here. Let’s take a look on the following type definition:

program Project26;
{$POINTERMATH ON}

type
  TCalibrationTable = array [0 .. 3] of byte;
  PCalibrationTable = ^TCalibrationTable;

Now I need 2 arrays, each of them having 3 elements of TCalibrationTable (ultimately they are 2-dimensional, 3 × 4 arrays). And also need a header which points to a pair of such array objects.

var
  table0: array [0 .. 2] of TCalibrationTable;
  table1: array [0 .. 2] of TCalibrationTable;

  header: array [0 .. 1] of PCalibrationTable;

Let’s initialize the header: the most comfortable way to access an array by a pointer is to assign it the first element’s address, then simply index the pointer to get an arbitrary element.

begin
  header[0] := @table0[0];
  header[1] := @table1[0];

Now, header[0] being a PCalibrationTable, I can use it to index it in order to get arbitrary TCalibrationTable typed elements from an array. In this way header[0][2] SHOULD BE a TCalibrationTable, that is, an array of 4 elements of byte.

But the following assignment will give a build error: Array type required.

  header[0][2][3] := 100;
end.

Why?

1

1 Answer 1

1

If you remove the pointer indirection from the header:

type
  TCalibrationTable = array [0 .. 3] of byte;
  PCalibrationTable = ^TCalibrationTable;
var
  header: array [0 .. 1] of PCalibrationTable;

you get this:

type
  TCalibrationTable = array [0 .. 3] of byte;
var
  header: array [0 .. 1] of TCalibrationTable;

or

var
  header: array [0 .. 1] of array [0 .. 3] of byte;

or

var
  header: array [0 .. 1, 0 .. 3] of byte;

In other words: a 2-dimensional array.

What you need is this:

type
  TCalibrationTable = array [0 .. 3] of byte;
  TCalibrationArr = ARRAY[0..2] OF TCalibrationTable;
  PCalibrationArr = ^TCalibrationArr;

var
  table0: TCalibrationArr;
  table1: TCalibrationArr;

  header: array [0 .. 1] of PCalibrationArr;

you can then do:

header[0] := @table0;
header[1] := @table1;
header[0][1][2] := 123;
Sign up to request clarification or add additional context in comments.

9 Comments

This is exactly I want to avoid as this trivial code is derived from a real one where things are a little bit complicated. Actually the length of table0 and table1 are not known at compile time, they are rather objects created dynamically, but from the point of view of redirection this thing is irrelevant.
By the way, your example should be rather used in the following way: header[0]^[1][2] := 123, am I right? As header[0] point directly to a 2-dimension array.
@ZoltánBíró header[0]^[1][2] := 123 and header[0][1][2] := 123 are the same in Delphi, just as MainForm.Caption is the same as MainForm^.Caption (MainForm is in reality a POINTER to an instance, but the delphi language allows omitting the pointer dereference when the compiler can do so without ambiguity).
@ZoltánBíró If you want to ask about arrays whose length is dynamic, shouldn't that information be in the question?
@DavidHeffernan, no, as it would complicate a lot the question and it’s irrelevant: I need rather an explanation why this doesn’t work, not necessarily a workaround. In case of a programming language an illogical behavior scares me much more than a task that I cannot solve myself.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.