问题
How can I to create multidimensional(2D, 3D, 4D)
arrays using GetMem and PointerMath
?
回答1:
GetMem()
only knows about 1-dimensional memory - you specify a byte count, it allocates that many bytes. Period. You would have to divide that memory up into sub-sections to handle them as multi-dimensional arrays, eg:
{$POINTERMATH ON}
var
numCols, numRows, iRow, iCol: Integer;
arr, pRow: PInteger; // an array of integers, for example
begin
numCols := ...;
numRows := ...;
GetMem(arr, (numCols * numRows) * SizeOf(Integer));
try
for iRow := 0 to numRows-1 do
begin
pRow := @arr[iRow * numCols];
for iCol := 0 to numCols-1 do
begin
// use pRow[iCol] as needed...
end;
end;
finally
FreeMem(arr);
end;
end;
To expand this to 3D, 4D, etc, simply multiply the initial allocation by the additional dimensions, and then index into the relevant sections as needed, eg:
{$POINTERMATH ON}
var
numX, numY, numZ, iX, iY, iZ: Integer;
arr, pX, pY: PInteger;
begin
numX := ...;
numY := ...;
numZ := ...;
GetMem(arr, (numX * numY * numZ) * SizeOf(Integer));
try
for iY := 0 to numY-1 do
begin
pY := @arr[iY * (numX * numZ)];
for iX := 0 to numX-1 do
begin
pX := @pY[iX * numZ];
for iZ := 0 to numZ-1 do
begin
// use pX[iZ] as needed...
end;
end;
end;
finally
FreeMem(arr);
end;
end;
回答2:
This is better without an extra variable.
var
I, J: Integer;
A: PInteger;
begin
GetMem(A, 10 * 10 * SizeOf(Integer));
for I := 0 to 10 - 1 do
for J := 0 to 10 - 1 do
PInteger(@A[I * 10])[J] := Random(10);
for I := 0 to 10 - 1 do
for J := 0 to 10 - 1 do
WriteLn(I,',',J,':',PInteger(@A[I * 10])[J]);
来源:https://stackoverflow.com/questions/32957977/using-getmem-for-allocation-of-multidimensional-arrays