使用 GetMem 分配多维数组

Using GetMem for Allocation of Multidimensional arrays

如何使用 GetMem 和 PointerMath 创建 multidimensional(2D, 3D, 4D) 数组?

GetMem() 只知道一维内存——你指定一个字节数,它分配那么多字节。时期。您必须将该内存分成多个子部分,以将它们作为多维数组处理,例如:

{$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;

要将其扩展到 3D、4D 等,只需将初始分配乘以额外维度,然后根据需要索引到相关部分,例如:

{$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;

没有额外的变量会更好。

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]);