Board index » delphi » Dynamic multi-dimensional array - how?

Dynamic multi-dimensional array - how?

Using Delphi 2.0, I need to dynamically allocate memory and reference
it as a two-dimensional array.  The techinfo.hlp on the CD says use
this technique for dynamically allocating an array:

Quote
>...you need to create an array type using the largest size you
>might possibly need.  When creating a type, no memory is actually
>allocated.  If you created a variable of that type, then the
>compiler will attempt to allocate the necessary memory for you.
>Instead, create a variable which is a pointer to that type.  This
>causes the compiler to only allocate the four bytes needed for the
>pointer.

>Before you can use the array, you need to allocate memory for it.  
>By using AllocMem, you will be able to control exactly how many
>bytes are allocated.  To determine the number of bytes you'll need
>to allocate, simply multiply the array size you want by the size of
>the individual array element.

This technique seems to work fine for a single-dimensional array, but
if I declare the type as a two-dimensional array, I get a
memory-protection fault when the outer loop that processes the first
dimension of the array moves past the first index value (i.e. from 1
to 2).

Anyone got any suggestions?  

Patrick Mills
plmi...@ix.netcom.com

 

Re:Dynamic multi-dimensional array - how?


Quote
In article <jcoyne.827688...@blue.weeg.uiowa.edu> jco...@blue.weeg.uiowa.edu (J. Coyne) writes:
>>Using Delphi 2.0, I need to dynamically allocate memory and reference
>>it as a two-dimensional array.  The techinfo.hlp on the CD says use
>>this technique for dynamically allocating an array:

Develop a class and use it.  End of story.

Re:Dynamic multi-dimensional array - how?


Quote
plmi...@ix.netcom.com (Patrick Mills) writes:
>Using Delphi 2.0, I need to dynamically allocate memory and reference
>it as a two-dimensional array.  The techinfo.hlp on the CD says use
>this technique for dynamically allocating an array:
>This technique seems to work fine for a single-dimensional array, but
>if I declare the type as a two-dimensional array, I get a
>memory-protection fault when the outer loop that processes the first
>dimension of the array moves past the first index value (i.e. from 1
>to 2).
>Anyone got any suggestions?  

The problem is  happening begauce the memory is allocated in a block.    
So  you are accessing outside the array.

The Solution : Pake an array to pointers to  arrays.

type  
        PArray  :^TArray;
        TArray : Array [1..10] of ^byte;
var
        My_array : Array [1..10] of PArray;

You have  to  be carefull,  and make sure you allocate both the Myarray,
and each subarray.   But this will  do  what you want.

----------------  This Signature (c) 1996 Gaijin Inc.
If a lunch break is when you take 30 minutes to take time off from
whatever important stuff you are doing to go eat, is a study break when
you take 30 minutes off from the important stuff you are doing to
study?  I think so...

Jason Coyne - Gaijin
jco...@blue.weeg.uiowa.edu Jason-Co...@Uiowa.edu
gai...@lust.isca.uiowa.edu http://odie.weeg.uiowa.edu/~jcoyne

Re:Dynamic multi-dimensional array - how?


Quote
plmi...@ix.netcom.com (Patrick Mills) wrote:
>Using Delphi 2.0, I need to dynamically allocate memory and reference
>it as a two-dimensional array.  The techinfo.hlp on the CD says use
>this technique for dynamically allocating an array:
>>...you need to create an array type using the largest size you
>>might possibly need.  When creating a type, no memory is actually
>>allocated.  If you created a variable of that type, then the
>>compiler will attempt to allocate the necessary memory for you.
>>Instead, create a variable which is a pointer to that type.  This
>>causes the compiler to only allocate the four bytes needed for the
>>pointer.

>>Before you can use the array, you need to allocate memory for it.  
>>By using AllocMem, you will be able to control exactly how many
>>bytes are allocated.  To determine the number of bytes you'll need
>>to allocate, simply multiply the array size you want by the size of
>>the individual array element.
>This technique seems to work fine for a single-dimensional array, but
>if I declare the type as a two-dimensional array, I get a
>memory-protection fault when the outer loop that processes the first
>dimension of the array moves past the first index value (i.e. from 1
>to 2).
>Anyone got any suggestions?  
>Patrick Mills
>plmi...@ix.netcom.com

This may  be a real dumb question, but when you allocate the array did you calculate the size as
x*y?

Such as if the array could be  myArray[100][100]
did you do:
(pseudocode - can't remember the syntax and I'm dead tired)
myArrayPtr = AllocMem(100*100);

Joe

Re:Dynamic multi-dimensional array - how?


I created a matrix object which is a child of Tmemorystream
TMatrix = class(TMemoryStream)
    rows,cols:longint;
    constructor create(r,c:longint); virtual;
    function item(r,c:longint):double;
    procedure setitem(r,c:longint;d:double);
    procedure setMatrix(r,c:longint);
    procedure zero;
    Procedure Pivot(r,c:Longint);
    Function Average(a:Longint):double;
    Function SumSquares(a:longint):double;
    Function Variance(a:Longint):double;
    function Max(a:LongInt):double;
    function Min(a:LongInt):double;
    Function StdDeviation(a:LongInt):double;
    function stdperiod(col,d1,d2:LongInt):double;
    function avgperiod(col,d1,d2:LongInt):double;
    function MaxPeriod(col,d1,d2:LongInt):double;
    function MinPeriod(col,d1,d2:LongInt):double;
    procedure readfile(var f:TFileStream); virtual;
    procedure writefile(var f:TFileStream); virtual;
    procedure savetofile(s:string);
    procedure loadfromfile(s:string)
    procedure writetext(s:string);
    procedure print(s:String)
    end;

with methods looking like ...

constructor TMatrix.create(r,c:longint);
begin
inherited create;
setmatrix(r,c);
end;

procedure TMatrix.SetMatrix(r,c:longint);
var
 x:longint;
begin
rows:=r;
cols:=c;
x:=sizeof(double)*r;
x:=x*c;
Clear;
SetSize(x);
zero;
end;

function TMatrix.item(r,c:longint):double;
var
 x:longint;
 d:double;
begin
x:=((r-1)*cols+(c-1))*sizeof(d);
d:=0;
if x<size then begin
   seek(x,0);
   read(d,sizeof(d));
   end;
item:=d;
end;
procedure TMatrix.setitem(r,c:longint;d:double);
var
 x:longint;
begin
x:=((r-1)*cols+(c-1))*sizeof(d);
if x<size then begin
   seek(x,0);
   write(d,sizeof(d));
   end;
end;
procedure TMatrix.Zero;
var
 i,j:longint;
begin
for i:=1 to rows do begin
    for j:=1 to cols do SetItem(i,j,0);
    end;
end;

I have used this object with very large matrix manipulation with pretty good
sucess.  Perhaps this approach will suit your needs.

Bill

In article <4j7s2d$...@news1.inlink.com>, jstra...@inlink.com (Joe Stratmann)
wrote:

Quote
>plmi...@ix.netcom.com (Patrick Mills) wrote:

>>Using Delphi 2.0, I need to dynamically allocate memory and reference
>>it as a two-dimensional array.  The techinfo.hlp on the CD says use
>>this technique for dynamically allocating an array:

>>>...you need to create an array type using the largest size you
>>>might possibly need.  When creating a type, no memory is actually
>>>allocated.  If you created a variable of that type, then the
>>>compiler will attempt to allocate the necessary memory for you.
>>>Instead, create a variable which is a pointer to that type.  This
>>>causes the compiler to only allocate the four bytes needed for the
>>>pointer.

>>>Before you can use the array, you need to allocate memory for it.  
>>>By using AllocMem, you will be able to control exactly how many
>>>bytes are allocated.  To determine the number of bytes you'll need
>>>to allocate, simply multiply the array size you want by the size of
>>>the individual array element.

>>This technique seems to work fine for a single-dimensional array, but
>>if I declare the type as a two-dimensional array, I get a
>>memory-protection fault when the outer loop that processes the first
>>dimension of the array moves past the first index value (i.e. from 1
>>to 2).

>>Anyone got any suggestions?  

>>Patrick Mills
>>plmi...@ix.netcom.com

>This may  be a real dumb question, but when you allocate the array did you
> calculate the size as
>x*y?

>Such as if the array could be  myArray[100][100]
>did you do:
>(pseudocode - can't remember the syntax and I'm dead tired)
>myArrayPtr = AllocMem(100*100);

>Joe

Re:Dynamic multi-dimensional array - how?


Quote
In article <31555cd8.3489...@ixnews2.ix.netcom.com> plmi...@ix.netcom.com (Patrick Mills) writes:
>Using Delphi 2.0, I need to dynamically allocate memory and reference
>it as a two-dimensional array.  The techinfo.hlp on the CD says use
>this technique for dynamically allocating an array:
>>...you need to create an array type using the largest size you
>>might possibly need.  When creating a type, no memory is actually
>>allocated.  If you created a variable of that type, then the
>>compiler will attempt to allocate the necessary memory for you.
>>Instead, create a variable which is a pointer to that type.  This
>>causes the compiler to only allocate the four bytes needed for the
>>pointer.

>>Before you can use the array, you need to allocate memory for it.  
>>By using AllocMem, you will be able to control exactly how many
>>bytes are allocated.  To determine the number of bytes you'll need
>>to allocate, simply multiply the array size you want by the size of
>>the individual array element.
>This technique seems to work fine for a single-dimensional array, but
>if I declare the type as a two-dimensional array, I get a
>memory-protection fault when the outer loop that processes the first
>dimension of the array moves past the first index value (i.e. from 1
>to 2).

Define a class.  Within the create-method of that class, store the dimensions,
allocate a chunk of memory of appropriate size, and store that in a "pointer
to integer."

Define a "read" and "write" method for the class, and in each method do the
multiplication, e.g.

        index :=  ((row - lowRow) * rowSize) + (col - lowCol);

Retrieve and return (or store) the value at that index.  Check bounds, too.

I assure you that this is exactly the sort of thing that the compiler
generates for you whenever you use an array and it is no less efficient.  
Things get interesting when you do re-size the array, but they're identical to
what Visual Basic does for you and a whole lot MORE efficient.

Resizeable arrays are not the norm in compiled languages.  They're simply a
Visual Basic feature that you grew used to.

/mr/

Re:Dynamic multi-dimensional array - how?


Quote
plmi...@ix.netcom.com (Patrick Mills) wrote:

<[on declaring huge arrays so you can use variable sized ones at run>

Quote
>This technique seems to work fine for a single-dimensional array, but
>if I declare the type as a two-dimensional array, I get a
>memory-protection fault when the outer loop that processes the first
>dimension of the array moves past the first index value (i.e. from 1
>to 2).

>Anyone got any suggestions?  

Did you make sure all the inner (left-most) dimensions were fixed? It is
only the last (right-most) dimension that can vary.

const
  MaxDim1 = <max index value of 1st>;
  MaxDim2 = <max index value of 2nd>;
  // etc.
  MaxDimN-1 = <max index value of N-1th>;
type
  MyBigArray = array[0..MaxDim1, 0..MaxDim2, <...>
    0..MaxDimN-1, 0..Maxint] of MyType;

This is NOT tested -- but I know from reading the docs that Delphi does
require array dimensions to be static (which they are in 99%+ of uses of
arrays.)

--
Brad Aisa <ba...@hookup.net>  web: http://www.hookup.net/~baisa/

1 Mises (M1.00) = 0.01 troy ounce gold; 1 Rand (1R) = 0.01 Mises

"The highest responsibility of philosophers is to serve as the
guardians and integrators of human knowledge."   -- Ayn Rand

Re:Dynamic multi-dimensional array - how?


I just puchased Delphi 2.0 and am wondering the following.

Is it possible to create a delphi application which contains no forms.  Just a quick and dirty
file parser or something like that.  It seems like it ought to be possible.

if at all possible please reply via email to t...@lantel.com.

                   Thanks in advance.

Other Threads