Como ilustración al manejo del casting explicado, te pongo el código usando esa técnica:
type AMatrix = array [0..0] of array of Double; PMatrix = ^AMatrix;
El código, creo que bastante claro:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; const // Tamaño de las matrices Rows: integer = 92 * 112; //10304 Cols: Integer = 40; // Precisión del reloj: 1/10000 seg. // Idea y forma de cálculo basada en: // [url]http://www.marteens.com/trick4c.htm[/url] // En teoría es lo más preciso PrecisionCounter = 10000; type // Nuestro tipo para matrices // 10304 * 40 * 8 = 3297280 bits // = 3220 Kb // aprox. 3,1445 Mb TMatrix = array of array of Double; AMatrix = array [0..0] of array of Double; PMatrix = ^AMatrix; TForm1 = class(TForm) Button1: TButton; Button2: TButton; Label1: TLabel; Label2: TLabel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; Matrix1: TMatrix; Matrix2: PMatrix; Start, Finish, Freq: Int64; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var i,j: Integer; begin // Aquí emplearemos el método "tradicional" // Activamos "cronómetro" QueryPerformanceCounter(Start); //Aqui el algoritmo: SetLength(Matrix1,Rows,Cols); // Método seguro. Si bien puede usarse // for <variable> := 0 to <valor-max> - 1 do // es conveniente el uso de Low() y High() for i := Low(Matrix1) to High(Matrix1) do for j := Low(Matrix1[1]) to High(Matrix1[1]) do Matrix1[i][j] := i + j; SetLength(Matrix1,0,0); // O también puede usarse Finalize() Matrix1 := nil; // preventiva // Paramos "cronómetro" QueryPerformanceCounter(Finish); Label1.Caption := '1/10000 seg: ' + FormatFloat('0,',(Finish - Start) * PrecisionCounter div Freq); end; procedure TForm1.Button2Click(Sender: TObject); var i,j: Integer; k: Cardinal; begin // Aquí emplearemos el método GetMem/FreeMem // Activamos "cronómetro" QueryPerformanceCounter(Start); //Aqui el algoritmo: Matrix2:= VirtualAlloc(nil, SizeOf(Pointer) * Rows + Rows * Cols * SizeOf(Double), MEM_COMMIT, PAGE_READWRITE); for k := 0 to Rows - 1 do PPointer(Cardinal(Matrix2) + k*SizeOf(Pointer))^:= Pointer(Cardinal(Matrix2)+SizeOf(Pointer)* Rows + Cols * SizeOf(double)* k); for i := 0 to Rows-1 do for j := 0 to Cols-1 do Matrix2[i][j] := i + j; VirtualFree(Matrix2, 0, MEM_RELEASE); // Paramos "cronómetro" QueryPerformanceCounter(Finish); Label2.Caption := '1/10000 seg: ' + FormatFloat('0,',(Finish - Start) * PrecisionCounter div Freq); end; procedure TForm1.FormCreate(Sender: TObject); begin // Calculamos la frecuencia a la que corre el reloj QueryPerformanceFrequency(freq); end; end.
Saludos.