Recent

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

rtusrghsdfhsfdhsdfhsfdhs

  • Full Member
  • ***
  • Posts: 162
2D, 3D Arrays
« on: October 06, 2015, 03:24:03 pm »
How to allocate 2D or 3D arrays with GetMem so they can be used with [][] or [][][] double or tripple pointers?

Preferably with a single GetMem.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8831
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: 2D, 3D Arrays
« Reply #1 on: October 06, 2015, 03:34:58 pm »
You can't, use real dynamic arrays instead. Maybe its possible by casting to the proper type (PPxxx for 2D, PPPxxx for 3D, define them yourself of course) but I'm not sure and it's a waste of time knowing that real dynamic arrays exist.

rvk

  • Hero Member
  • *****
  • Posts: 6885
Re: 2D, 3D Arrays
« Reply #2 on: October 06, 2015, 03:36:11 pm »
Not sure how this would go with GetMem. (I think you'll need a loop)
But for an array of an array (dynamic) you can use SetLength.

Code: Pascal  [Select][+][-]
  1. var
  2.   a: array of array of byte;
  3. begin
  4.   SetLength(a, 2, 3);
  5.   a[1][1] := 2;
  6.   //...
  7.  

(see also multi-dimensional arrays in SetLength)
« Last Edit: October 06, 2015, 03:38:20 pm by rvk »

rtusrghsdfhsfdhsdfhsfdhs

  • Full Member
  • ***
  • Posts: 162
Re: 2D, 3D Arrays
« Reply #3 on: October 06, 2015, 03:38:58 pm »
In C you would do it with a malloc so how to do it in FPC using the same approach?

rvk

  • Hero Member
  • *****
  • Posts: 6885
Re: 2D, 3D Arrays
« Reply #4 on: October 06, 2015, 03:43:41 pm »
In C you would do it with a malloc so how to do it in FPC using the same approach?
Use SetLength like I showed you.

(If there is any reason you can't use SetLength you might want to show some example of your multi-dim array)

Leledumbo

  • Hero Member
  • *****
  • Posts: 8831
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: 2D, 3D Arrays
« Reply #5 on: October 06, 2015, 07:09:55 pm »
In C you would do it with a malloc so how to do it in FPC using the same approach?
No different, just substitute the corresponding functions, if you have the C code. OK, I'll open the secret a bit. The implementation can be flat memory area (single GetMem, casted to correct dimension division upon use) or random non-contiguous memory area (multiple GetMem, just like the existing dynamic array implementation, which essentially is a pointer to pointer to pointer to...). But as I said, unless for low level learning purpose, this is a waste of time. rvk has showed why it's not worth doing it the C way.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: 2D, 3D Arrays
« Reply #6 on: October 06, 2015, 07:29:12 pm »
Code: Delphi  [Select][+][-]
  1. program project1;
  2.  
  3. type
  4.   P3DIntArray = ^T3DIntArray;
  5.   T3DIntArray = array[0..0,0..0,0..0] of integer;
  6.  
  7. Var
  8.   IntArray : P3DIntArray;
  9.   vDim1 :Integer;
  10.   vDim2 :Integer;
  11.   vDim3 :Integer;
  12. begin
  13.   IntArray := GetMem(SizeOf(Integer)*5*4*9);
  14.   Randomize;
  15.   for vDim1 := 0 to 4 do
  16.     for vDim2 := 0 to 3 do
  17.       for vDim3 := 0 to 9 do begin
  18.         IntArray^[vDim1][vDim2][vDim3] := Random(150);
  19.       end;
  20.  
  21.   for vDim1 := 0 to 4 do
  22.     for vDim2 := 0 to 3 do
  23.       for vDim3 := 0 to 9 do begin
  24.         WriteLn(vDim1+1,',',vDim2+1,',',vDim3+1,':',IntArray^[vDim1,vDim2,vDim3]);
  25.       end;
  26.   ReadLn;
  27. end.
  28. end;
  29.  
old style dynamic arrays. Use at your own risk.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

rtusrghsdfhsfdhsdfhsfdhs

  • Full Member
  • ***
  • Posts: 162
Re: 2D, 3D Arrays
« Reply #7 on: October 06, 2015, 07:49:18 pm »
Another approach, possibly faster.

Code: Pascal  [Select][+][-]
  1. {$POINTERMATH ON}
  2. var
  3.   numCols, numRows, iRow, iCol: Integer;
  4.   arr, pRow: PInteger; // an array of integers, for example
  5. begin
  6.   numCols := ...;
  7.   numRows := ...;
  8.   GetMem(arr, (numCols * numRows) * SizeOf(Integer));
  9.   try
  10.     for iRow := 0 to numRows-1 do
  11.     begin
  12.       pRow := @arr[iRow * numCols];
  13.       for iCol := 0 to numCols-1 do
  14.       begin
  15.         // use pRow[iCol] as needed...
  16.       end;
  17.     end;
  18.   finally
  19.     FreeMem(arr);
  20.   end;
  21. end;

rvk

  • Hero Member
  • *****
  • Posts: 6885
Re: 2D, 3D Arrays
« Reply #8 on: October 06, 2015, 07:55:33 pm »
Another approach, possibly faster.
Possibly, but that way you don't have your [][] or [][][] notation.

(like you specified)
...so they can be used with [][] or [][][] double or tripple pointers?

Either way, for Pascal, the dynamic array way is much better and you have your [][] or [][][] notation (without worrying about range-check errors).


(Did you benchmark both methods to see if the dynamic array is really so much slower?)

rtusrghsdfhsfdhsdfhsfdhs

  • Full Member
  • ***
  • Posts: 162
Re: 2D, 3D Arrays
« Reply #9 on: October 06, 2015, 08:09:58 pm »
SetLength has GetMem in it. Maybe more than one. So yes it will be slower.  8-)

Btw taazz you forgot to free it.  ::)
« Last Edit: October 06, 2015, 08:12:48 pm by Fiji »

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: 2D, 3D Arrays
« Reply #10 on: October 06, 2015, 08:13:00 pm »
SetLength has GetMem in it. Maybe more than one. So yes it will be slower.  8-)
setlength will preserve the existing data when expanding the dimensions of an existing array getmem will not.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

rvk

  • Hero Member
  • *****
  • Posts: 6885
Re: 2D, 3D Arrays
« Reply #11 on: October 06, 2015, 08:15:00 pm »
SetLength has GetMem in it. Maybe more than one. So yes it will be slower.  8-)
How many times are you going to call SetLength?
If the memory access is fast enough, then calling SetLength once doesn't really matter.

If GetMem gets called thousands of times (each with different dimensions), then yes, you could go with the method taazz or Remy showed you. (the upside of taazzs one being it has the [][] notation)

(But do your benchmarking beforehand to check if it's really necessary.)
« Last Edit: October 06, 2015, 08:17:02 pm by rvk »

rtusrghsdfhsfdhsdfhsfdhs

  • Full Member
  • ***
  • Posts: 162
Re: 2D, 3D Arrays
« Reply #12 on: October 06, 2015, 08:19:42 pm »
SetLength has GetMem in it. Maybe more than one. So yes it will be slower.  8-)
setlength will preserve the existing data when expanding the dimensions of an existing array getmem will not.

Thats why you use RealocMem ;) Also regular array is reference counted. Another huge no no for performance critical code.

rvk

  • Hero Member
  • *****
  • Posts: 6885
Re: 2D, 3D Arrays
« Reply #13 on: October 06, 2015, 08:22:49 pm »
How is the way taazz showed you different from C?

Could you show how you did this (the [][] notation) in C?

Also regular array is reference counted. Another huge no no for performance critical code.
I wasn't aware that performance was part of your original question. You didn't mention it.
« Last Edit: October 06, 2015, 08:24:26 pm by rvk »

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: 2D, 3D Arrays
« Reply #14 on: October 06, 2015, 09:36:13 pm »
SetLength has GetMem in it. Maybe more than one. So yes it will be slower.  8-)
setlength will preserve the existing data when expanding the dimensions of an existing array getmem will not.

Thats why you use RealocMem ;) Also regular array is reference counted. Another huge no no for performance critical code.
Have you tried it? are you sure that the data are preserved in correct cells?
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

 

TinyPortal © 2005-2018