Recent

Author Topic: 2D, 3D Arrays  (Read 15589 times)

rvk

  • Hero Member
  • *****
  • Posts: 6886
Re: 2D, 3D Arrays
« Reply #30 on: October 12, 2015, 11:05:37 am »
Even on 64 big?? I thought 2G is not limited on 64 bit.
No, I meant you do a GetMem of 5 * 5 * 5 * SizeOf(T) and with array [0..MaxInt div SizeOf(T) - 1, 0..MaxInt div SizeOf(T) - 1, 0..MaxInt div SizeOf(T) - 1] the following element is at a memory location beyond that:

Let's say SizeOf(T) is 1 byte (Byte)

[0..MaxInt div 1 - 1, 0..MaxInt div 1 - 1, 0..MaxInt div 1 - 1]
Then A[1][0][0] is at MaxInt * MaxInt location.
That's... uuuh... A[4611686014132421000] (or somewhere around that :))
That is way more than the 5 * 5 * 5 * 1 = 125 bytes you reserved.


So you need to use array[0..0, 0..0, 0..0] of T; and this to get to the correct element:
A[X * maxX][Y * maxX * maxY][Z]
« Last Edit: October 12, 2015, 11:26:42 am by rvk »

rtusrghsdfhsfdhsdfhsfdhs

  • Full Member
  • ***
  • Posts: 162
Re: 2D, 3D Arrays
« Reply #31 on: October 12, 2015, 01:35:27 pm »
I did it like this in C++ but can it be optimized?

Code: Pascal  [Select][+][-]
  1. #define array2d(a, x, y, width) a[x + y * width]
  2. #define array3d(a, x, y, z, width, height) a[x + (y * width) + (z * width * height)]
  3. #define array3d(a, x, y, z, width, height) a[x * height * width + y * height + z]

rvk

  • Hero Member
  • *****
  • Posts: 6886
Re: 2D, 3D Arrays
« Reply #32 on: October 12, 2015, 02:27:16 pm »
I did it like this in C++ but can it be optimized?
Code: [Select]
#define array2d(a, x, y, width) a[x + y * width]
#define array3d(a, x, y, z, width, height) a[x + (y * width) + (z * width * height)]
#define array3d(a, x, y, z, width, height) a[x * height * width + y * height + z]
So the way you show it C++ also doesn't know the [][] notation and you need to cast it to a flat-memory block and calculate the position yourself.

I did find this:
Quote
The other way to use the array objects is more like regular array notation. The function operator () allows the object to be used like an array, except instead of writing a [j] we will write (i,j). (The reason that we do not use the standard array notation has to do with the array notation convention in C++. Basically, we can only define an operator [] and not an operator [][].)

So you could create a class around it with get(x,y,z) to retrieve the correct value. In that method you can calculate the position within memory[] and return the correct value.

Otherwise you would need to use
a[x*maxx*maxy + y*maxx + z]
just like you do in C++ (which is probably the fastest way).

So do you need optimization of speed or ease of use?

B.T.W. using a[x*maxx*maxy + y*maxx + z] probably isn't slower than a[ x ][ y ][ z ] because for a[ x ][ y ][ z ] the compiler will still insert the calculation for [ x ][ y ][ z ].

rtusrghsdfhsfdhsdfhsfdhs

  • Full Member
  • ***
  • Posts: 162
Re: 2D, 3D Arrays
« Reply #33 on: October 12, 2015, 02:50:26 pm »
I did try this. But how to do it for 2D arrays. Btw this is ported from C++.

Code: Pascal  [Select][+][-]
  1. const
  2.   Dim1 = 5;
  3.   Dim2 = 5;
  4.   Dim3 = 5;
  5.  
  6. var
  7.   A: PPPInteger;
  8.   X, Y, Z: Integer;
  9. begin
  10.   GetMem(A, (Dim1 * SizeOf(PInteger)) + (Dim1 * Dim2 * SizeOf(PPInteger)) + (Dim1 * Dim2 * Dim3 * SizeOf(Integer)));
  11.  
  12.   for X := 0 to Dim1 - 1 do
  13.   begin
  14.     A[X] := PPInteger((A + Dim1) + X * Dim2);
  15.  
  16.     for Y := 0 to Dim2 - 1 do
  17.     A[X][Y] := PInteger((A + Dim1 + Dim1 * Dim2) + X * Dim2 * Dim3 + Y * Dim3);
  18.   end;
  19.  
  20.   for X := 0 to Dim1 - 1 do
  21.   for Y := 0 to Dim2 - 1 do
  22.   for Z := 0 to Dim3 - 1 do
  23.   A[X][Y][Z] := (X * 100 + Y);
  24.  
  25.   for X := 0 to Dim1 - 1 do
  26.   for Y := 0 to Dim2 - 1 do
  27.   for Z := 0 to Dim3 - 1 do
  28.   WriteLn(X, ',', Y, ',', Z, ':', A[X][Y][Z]);
  29.  
  30.   FreeMem(A);
  31.  
  32.   ReadLn;
  33. end.

rvk

  • Hero Member
  • *****
  • Posts: 6886
Re: 2D, 3D Arrays
« Reply #34 on: October 12, 2015, 03:12:19 pm »
I did try this. But how to do it for 2D arrays. Btw this is ported from C++.
With just 2 dimensions you wouldn't need Dim3.
So you can remove Dim3, make A: PPInteger and remove all inner for/next loops.

Code: Pascal  [Select][+][-]
  1. {$POINTERMATH ON}
  2.  
  3. const
  4.   Dim1 = 5;
  5.   Dim2 = 5;
  6.  
  7. var
  8.   A: PPInteger;
  9.   X, Y, Z, C: Integer;
  10. begin
  11.   GetMem(A, (Dim1 * SizeOf(PInteger)) + (Dim1 * Dim2 * SizeOf(PPInteger)) );
  12.  
  13.   for X := 0 to Dim1 - 1 do
  14.   begin
  15.     A[X] := PInteger((A + Dim1) + X * Dim2);
  16.   end;
  17.  
  18.   C := 0;
  19.   for X := 0 to Dim1 - 1 do
  20.   for Y := 0 to Dim2 - 1 do
  21.   begin
  22.     A[X][Y] := C;
  23.     Inc(C);
  24.   end;
  25.  
  26.   for X := 0 to Dim1 - 1 do
  27.   for Y := 0 to Dim2 - 1 do
  28.   WriteLn(X, ',', Y, ':', A[X][Y]);
  29.  
  30.   FreeMem(A);
  31.  
  32.   ReadLn;
  33. end.

Thaddy

  • Hero Member
  • *****
  • Posts: 18365
  • Here stood a man who saw the Elbe and jumped it.
Re: 2D, 3D Arrays
« Reply #35 on: October 12, 2015, 03:34:19 pm »
 Since it is Fiji, here's one for Fiji: ;)

That was a really stupid question to begin with. Luckily there are some good answers on how to handle that.
- First: total size needs to be known (answered)
- Second: original question seems to have some weird understanding about how compiled languages work (answered multiple times)
- Third:original question seems to be covered in the standard documentation.
- fourth:All of this at the cost of range checks.

and fifth:

Questioneer must be very careful not to be seen as a Troll, which he does not seem to care about very much.

This seems to stem from a common misconception of the C or C related languages by the way.
In Pascal it is as written above perfectly possible to define arrays like[0..0] in any dimension and use indexes to the elements at the cost of range checks. That is: if you know how to handle memory. The one who asked this question doesn't have a clue about how a compiled language works - or memory allocation - but at least I'll give him that it makes people think. Just do not ask for the obviously impossible: indexing memory you do not know the size of before hand and expect the compiler to handle any overflows at run-time (that would be a script, or C or badly written Pascal!).
That would be possible mathematically using quantum physics, though ;)

Marco just fixed a bug that is based on this same misconception (regarding a COM issue) a couple of weeks ago.
« Last Edit: October 12, 2015, 04:30:52 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

Thaddy

  • Hero Member
  • *****
  • Posts: 18365
  • Here stood a man who saw the Elbe and jumped it.
Re: 2D, 3D Arrays
« Reply #36 on: October 12, 2015, 04:25:25 pm »
But how about a weak reference to memory, btw?: type a = weak array[0..infinity;0..infinity] of integer;
Declare an array as weak, thus allowing for the impossible.
That can be done - pretty easy - but be equally stupid, Nah, ain't going to happen ;) I am stupid enough already.

And how to define infinity minus 1?
« Last Edit: October 12, 2015, 04:28:07 pm by Thaddy »
Due to censorship, I changed this to "Nelly the Elephant". Keeps the message clear.

 

TinyPortal © 2005-2018