home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / lang / pascal / 4890 < prev    next >
Encoding:
Internet Message Format  |  1992-08-17  |  10.3 KB

  1. Path: sparky!uunet!munnari.oz.au!yoyo.aarnet.edu.au!dstos3.dsto.gov.au!zodiac.dsto.oz.au!st_waldman
  2. From: st_waldman@zodiac.dsto.oz.au
  3. Newsgroups: comp.lang.pascal
  4. Subject: Re: Arrays > 64K -- New source code
  5. Message-ID: <1992Aug18.130157.1@zodiac.dsto.oz.au>
  6. Date: 18 Aug 92 02:01:57 GMT
  7. Organization: D.S.T.O. Aeronautical Research Laboratory
  8. Lines: 396
  9. Nntp-Posting-Host: zodiac.dsto.gov.au
  10.  
  11. Hi,
  12.  
  13. I have also written some memory allocation routines that allow me to
  14. create arrays larger than 64KB. They handle Turbo Pascal REAL, DOUBLE,
  15. SINGLE and INTEGER arrays, of one or two dimensions.
  16.  
  17. The source code is provided below, and can be used freely by anyone who
  18. is interested. A small test program is also provided, and was compiled
  19. and run under Turbo Pascal 6.0. As 5 x 60000 = 300000 bytes of memory is
  20. allocated, you may not be able to run the test program from within TP's
  21. IDE. I did add some comments here, though, so hopefully it will still work.
  22.  
  23. As written, the array indexing is assumed to start from 0, as this was
  24. the most convenient definition for my work. It is possible to change this
  25. to suit your needs by modifying some TYPE declarations in the MATMEM unit.
  26.  
  27. You will also note that the upper bound of the array type in the TYPE
  28. declaration is set to the maximum possible. If you use a smaller range,
  29. then there may be the risk of errors as range checking will not be
  30. effective. Again, these limits can be changed to something smaller if
  31. required.
  32.  
  33. The array referencing is fairly intuitive (at least I think so!). For
  34. example:
  35.  
  36.      A[I,J]    is referenced as   A^[I]^[J]
  37.  
  38. so existing code can be easily converted, particularly if your editor has
  39. a macro facility so that you can do some repetitive editing.
  40.  
  41. My routines use the standard GetMem and FreeMem procedures, so they
  42. may even be portable to Turbo Pascal For Windows. If someone would
  43. like to try my code in that environment, please let me know how you go.
  44.  
  45. Regards...
  46.  
  47. Witold Waldman
  48.  
  49. WITOLD@HOTBLK.DSTO.GOV.AU
  50.  
  51.  
  52.  
  53.  
  54. {--------------------------------------------------------------------------}
  55.  
  56. { Test program for trying out one of the matrix memory allocation routines }
  57. { contained in the MATMEM unit.                                            }
  58.  
  59. Program TestMATMEM(Input,Output);
  60.  
  61. Uses Crt,MATMEM;
  62.  
  63. var
  64.   I,J   : integer;   { Loop counters                                  }
  65.   NRmax : word;      { Maximum number of rows in 2D array             }
  66.   NCmax : word;      { Maximum number of columns in 2D array          }
  67.   A     : pArraySS;  { Pointer to 2D array of single precision values }
  68.  
  69. begin
  70.  
  71.   NRmax :=     5;
  72.   NCmax := 15000;    { 15000*4 bytes = 60000 bytes per row }
  73.  
  74.   Writeln('Memory on heap before array allocation = ',MemAvail,' bytes');
  75.  
  76.   A := NewArraySS(NRmax,NCmax);
  77.  
  78.   Writeln('Memory on heap after  array allocation = ',MemAvail,' bytes');
  79.  
  80.   If A = nil then
  81.     begin
  82.     Writeln;
  83.     Writeln('NewArray memory allocation request failed.');
  84.     Halt;
  85.     end;
  86.  
  87.   { Place some simple numbers in the array we have created }
  88.  
  89.   For I := 1 to NRmax do
  90.     For J := 1 to NCmax do
  91.       begin
  92.       A^[I]^[J] := I + J;
  93.       end;
  94.  
  95.   Writeln;
  96.   Writeln('Print out of value in first and last elements:');
  97.   Writeln;
  98.  
  99.   I := 1;
  100.   J := 1;
  101.  
  102.   Writeln(I:10,J:10,A^[I]^[J]:15:2);
  103.  
  104.   I := NRmax;
  105.   J := NCmax;
  106.  
  107.   Writeln(I:10,J:10,A^[I]^[J]:15:2);
  108.  
  109.   { Do the right thing: clean up your own rubbish }
  110.  
  111.   A := DisposeArraySS(A,NRmax,NCmax);
  112.  
  113. end.
  114.  
  115. {--------------------------------------------------------------------------}
  116.  
  117. { Source code for MATMEM unit }
  118.  
  119. UNIT MATMEM;
  120.  
  121. INTERFACE
  122.  
  123. const
  124.   PtrSize         = SizeOf(Pointer);
  125.   MaxSegmentSize  = 65535;
  126.   MaxSizeArrayPtr = MaxSegmentSize div PtrSize;
  127.   MaxSizeArrayR   = MaxSegmentSize div SizeOf(Real);
  128.   MaxSizeArrayS   = MaxSegmentSize div SizeOf(Single);
  129.   MaxSizeArrayD   = MaxSegmentSize div SizeOf(Double);
  130.   MaxSizeArrayI   = MaxSegmentSize div SizeOf(Integer);
  131.  
  132. type
  133.   ArrayPtr = array [0..MaxSizeArrayPtr-1] of Pointer;
  134.   ArrayR   = array [0..MaxSizeArrayR-1  ] of Real;
  135.   ArrayS   = array [0..MaxSizeArrayS-1  ] of Single;
  136.   ArrayD   = array [0..MaxSizeArrayD-1  ] of Double;
  137.   ArrayI   = array [0..MaxSizeArrayI-1  ] of Integer;
  138.  
  139.   ArrayRR  = array [0..MaxSizeArrayPtr-1] of ^ArrayR;
  140.   ArraySS  = array [0..MaxSizeArrayPtr-1] of ^ArrayS;
  141.   ArrayDD  = array [0..MaxSizeArrayPtr-1] of ^ArrayD;
  142.   ArrayII  = array [0..MaxSizeArrayPtr-1] of ^ArrayI;
  143.  
  144.   pArrayR  = ^ArrayR;
  145.   pArrayS  = ^ArrayS;
  146.   pArrayD  = ^ArrayD;
  147.   pArrayI  = ^ArrayI;
  148.  
  149.   pArrayRR = ^ArrayRR;
  150.   pArraySS = ^ArraySS;
  151.   pArrayDD = ^ArrayDD;
  152.   pArrayII = ^ArrayII;
  153.  
  154. function DisposeArrayS(A:Pointer; Nmax:Word):Pointer;
  155.  
  156. function NewArrayS(Nmax:Word):Pointer;
  157.  
  158. function DisposeArrayD(A:Pointer; Nmax:Word):Pointer;
  159.  
  160. function NewArrayD(Nmax:Word):Pointer;
  161.  
  162. function DisposeArrayI(A:Pointer; Nmax:Word):Pointer;
  163.  
  164. function NewArrayI(Nmax:Word):Pointer;
  165.  
  166. function DisposeArrayR(A:Pointer; Nmax:Word):Pointer;
  167.  
  168. function NewArrayR(Nmax:Word):Pointer;
  169.  
  170. function DisposeArraySS(A:Pointer; NRmax,NCmax:Word):Pointer;
  171.  
  172. function NewArraySS(NRmax,NCmax:Word):Pointer;
  173.  
  174. function DisposeArrayDD(A:Pointer; NRmax,NCmax:Word):Pointer;
  175.  
  176. function NewArrayDD(NRmax,NCmax:Word):Pointer;
  177.  
  178. function DisposeArrayII(A:Pointer; NRmax,NCmax:Word):Pointer;
  179.  
  180. function NewArrayII(NRmax,NCmax:Word):Pointer;
  181.  
  182. function DisposeArrayRR(A:Pointer; NRmax,NCmax:Word):Pointer;
  183.  
  184. function NewArrayRR(NRmax,NCmax:Word):Pointer;
  185.  
  186. IMPLEMENTATION
  187.  
  188. {==============================================================================}
  189.  
  190. function DisposeArray1D(A:Pointer; Nmax:Word; DataSize:Integer):Pointer;
  191.  
  192. begin
  193.   If A <> nil then
  194.     begin
  195.     FreeMem(A,(Nmax+1)*DataSize);
  196.     DisposeArray1D := nil;
  197.     end;
  198. end;
  199.  
  200. {==============================================================================}
  201.  
  202. function NewArray1D(Nmax:Word; DataSize:Integer):Pointer;
  203.  
  204. var
  205.   MemP : Word;
  206.   P    : Pointer;
  207.  
  208. begin
  209.   MemP := (Nmax+1)*DataSize;
  210.   If MaxAvail >= MemP then
  211.     GetMem(P,MemP)
  212.   else
  213.     P := nil;
  214.   NewArray1D := P;
  215. end;
  216.  
  217. {==============================================================================}
  218.  
  219. function DisposeArray2D(A:Pointer; NRmax,NCmax:Word; DataSize:Integer):Pointer;
  220.  
  221. var
  222.   I : Word;
  223.   Q : ^ArrayPtr;
  224.  
  225. begin
  226.   If A <> nil then
  227.     begin
  228.     Q := A;
  229.     For I := 0 to NRmax do
  230.       begin
  231.       If Q^[I] <> nil then
  232.         FreeMem(Q^[I],(NCmax+1)*DataSize);
  233.       end;
  234.     FreeMem(A,(NRmax+1)*PtrSize);
  235.     DisposeArray2D := nil;
  236.     end;
  237. end;
  238.  
  239. {==============================================================================}
  240.  
  241. function NewArray2D(NRmax,NCmax:Word; DataSize:Integer):Pointer;
  242.  
  243. var
  244.   Error : Boolean;
  245.   I     : Word;
  246.   MemP  : Word;        { Memory for pointers to each row of data }
  247.   MemR  : Word;        { Memory for row of data                  }
  248.   P     : ^ArrayPtr;
  249.  
  250. begin
  251.   MemP := (NRmax+1)*PtrSize;
  252.   If MaxAvail >= MemP then
  253.     GetMem(P,MemP)
  254.   else
  255.     P := nil;
  256.   If P <> nil then
  257.     begin
  258.     Error := false;
  259.     MemR  := (NCmax+1)*DataSize;
  260.     For I := 0 to NRmax do
  261.       begin
  262.       If MaxAvail >= MemR then
  263.         GetMem(P^[I],MemR)
  264.       else
  265.         begin
  266.         Error := true;
  267.         P^[I] := nil;
  268.         end;
  269.       end;
  270.     If Error then
  271.       begin
  272.       P := DisposeArray2D(P,NRmax,NCmax,DataSize);
  273.       end;
  274.     end;
  275.   NewArray2D := P;
  276. end;
  277.  
  278. {==============================================================================}
  279.  
  280. function DisposeArrayS(A:Pointer; Nmax:Word):Pointer;
  281.  
  282. begin
  283.   DisposeArrayS := DisposeArray1D(A,Nmax,SizeOf(Single));
  284. end;
  285.  
  286. {==============================================================================}
  287.  
  288. function NewArrayS(Nmax:Word):Pointer;
  289.  
  290. begin
  291.   NewArrayS := NewArray1D(Nmax,SizeOf(Single));
  292. end;
  293.  
  294. {==============================================================================}
  295.  
  296. function DisposeArrayD(A:Pointer; Nmax:Word):Pointer;
  297.  
  298. begin
  299.   DisposeArrayD := DisposeArray1D(A,Nmax,SizeOf(Double));
  300. end;
  301.  
  302. {==============================================================================}
  303.  
  304. function NewArrayD(Nmax:Word):Pointer;
  305.  
  306. begin
  307.   NewArrayD := NewArray1D(Nmax,SizeOf(Double));
  308. end;
  309.  
  310. {==============================================================================}
  311.  
  312. function DisposeArrayI(A:Pointer; Nmax:Word):Pointer;
  313.  
  314. begin
  315.   DisposeArrayI := DisposeArray1D(A,Nmax,SizeOf(Integer));
  316. end;
  317.  
  318. {==============================================================================}
  319.  
  320. function NewArrayI(Nmax:Word):Pointer;
  321.  
  322. begin
  323.   NewArrayI := NewArray1D(Nmax,SizeOf(Integer));
  324. end;
  325.  
  326. {==============================================================================}
  327.  
  328. function DisposeArrayR(A:Pointer; Nmax:Word):Pointer;
  329.  
  330. begin
  331.   DisposeArrayR := DisposeArray1D(A,Nmax,SizeOf(Real));
  332. end;
  333.  
  334. {==============================================================================}
  335.  
  336. function NewArrayR(Nmax:Word):Pointer;
  337.  
  338. begin
  339.   NewArrayR := NewArray1D(Nmax,SizeOf(Real));
  340. end;
  341.  
  342. {==============================================================================}
  343.  
  344. function DisposeArraySS(A:Pointer; NRmax,NCmax:Word):Pointer;
  345.  
  346. begin
  347.   DisposeArraySS := DisposeArray2D(A,NRmax,NCmax,SizeOf(Single));
  348. end;
  349.  
  350. {==============================================================================}
  351.  
  352. function NewArraySS(NRmax,NCmax:Word):Pointer;
  353.  
  354. begin
  355.   NewArraySS := NewArray2D(NRmax,NCmax,SizeOf(Single));
  356. end;
  357.  
  358. {==============================================================================}
  359.  
  360. function DisposeArrayDD(A:Pointer; NRmax,NCmax:Word):Pointer;
  361.  
  362. begin
  363.   DisposeArrayDD := DisposeArray2D(A,NRmax,NCmax,SizeOf(Double));
  364. end;
  365.  
  366. {==============================================================================}
  367.  
  368. function NewArrayDD(NRmax,NCmax:Word):Pointer;
  369.  
  370. begin
  371.   NewArrayDD := NewArray2D(NRmax,NCmax,SizeOf(Double));
  372. end;
  373.  
  374. {==============================================================================}
  375.  
  376. function DisposeArrayII(A:Pointer; NRmax,NCmax:Word):Pointer;
  377.  
  378. begin
  379.   DisposeArrayII := DisposeArray2D(A,NRmax,NCmax,SizeOf(Integer));
  380. end;
  381.  
  382. {==============================================================================}
  383.  
  384. function NewArrayII(NRmax,NCmax:Word):Pointer;
  385.  
  386. begin
  387.   NewArrayII := NewArray2D(NRmax,NCmax,SizeOf(Integer));
  388. end;
  389.  
  390. {==============================================================================}
  391.  
  392. function DisposeArrayRR(A:Pointer; NRmax,NCmax:Word):Pointer;
  393.  
  394. begin
  395.   DisposeArrayRR := DisposeArray2D(A,NRmax,NCmax,SizeOf(Real));
  396. end;
  397.  
  398. {==============================================================================}
  399.  
  400. function NewArrayRR(NRmax,NCmax:Word):Pointer;
  401.  
  402. begin
  403.   NewArrayRR := NewArray2D(NRmax,NCmax,SizeOf(Real));
  404. end;
  405.  
  406. END.
  407.