Board index » delphi » Dynamic Array Size

Dynamic Array Size

I would like to find out is there anyway I can manipulate the size of an array instead of pre-define it ? Something like :

        Ar : Array[n1..n2]

where n1 and n2 is defined by program during execution.

It will be even more interesting if I can increase or decrease the elements in the array.

Thanks for any help in advance.

Edward Terng
MicroForest Systems (Malaysia)
edte...@pc.jaring.my

 

Re:Dynamic Array Size


Quote
Edward Terng <edte...@pc.jaring.my> wrote:
>I would like to find out is there anyway I can manipulate the size of an array instead of pre-define it ? Something like :
>    Ar : Array[n1..n2]
>where n1 and n2 is defined by program during execution.
>It will be even more interesting if I can increase or decrease the elements in the array.
>Thanks for any help in advance.
>Edward Terng
>MicroForest Systems (Malaysia)
>edte...@pc.jaring.my

Sorry, you're in the wrong group/language - neither Pascal nor Fortran
ever did allow dynamic array allocation in this fashion, although both
Algol and PL/I do.

Novice Fortran programmer have claimed that you can do it, but that is
really a misunderstanding of the language!

(Now if you're running Algol on a Burrough's machine however you can
really have fun playing with dynamic arrays and the Resize
function!!!!)

Re:Dynamic Array Size


Quote
On Thu, 20 Jun 1996, Edward Terng wrote:
> I would like to find out is there anyway I can manipulate the size of an array instead of pre-define it ? Something like :

>    Ar : Array[n1..n2]

> where n1 and n2 is defined by program during execution.

> It will be even more interesting if I can increase or decrease the elements in the array.

> Thanks for any help in advance.

> Edward Terng
> MicroForest Systems (Malaysia)
> edte...@pc.jaring.my>

To solve this problem, I'm going to propose  several basic ways.
But, you can also mix them to obtain the appropiate solution to your
problem:  

- Using an "array" structure based on the heap memory:

   { dato =   type of the element of the "array" structure }

   puntero = ^dato;

   tindex =   { e.g } byte; {type of index}

   narray = record
       n1,n2:  tindex;
        L:   puntero;    
      end;

Next, you wold have to design routines to handle this array
structure.

- The following way is based on the OOP (Object Oriented
Programming)

      narray = object
         n1: tindex;
         v: array[0..max] of dato;
         procedure init(var nn1:tindex)
         function out-dato( var i : tindex);
         procedure in-dato(var i: tindex; var d: dato);
        end;

procedure narray.init(var nn1: tindex);
  begin
     n1:= nn1;
  end;

function narray.out-dato(i: tindex): dato;
  begin
     elem:= v[i - n1 ];
  end;

procedure narray.in-dato(var i: tindex; var d: dato);
  begin
     v[i-n1] := d;
  end;

Yours faithfully

             Francisco Antonio Ocan~a Lara
    Department of Statistics and Operations Research
                University of Granada (Spain)
 School of Pharmacy    |\  tel: +(34-58) 243878, +(34-58) 243908
Campus de Cartuja s.n. | |  fax: +(34-58) 243908
18071-Granada (Spain)  |/     e-mail: foc...@platon.ugr.es

Re:Dynamic Array Size


In article <1996Jun20.012504.27...@arl.mil>,
   Edward Terng <edte...@pc.jaring.my> wrote:
]-I would like to find out is there anyway I can manipulate the size of an
]-array instead of pre-define it ? Something like :
]-
]-      Ar : Array[n1..n2]
]-
]-where n1 and n2 is defined by program during execution.
]-
]-It will be even more interesting if I can increase or decrease the elements
]-in the array.

best (only?) way is to make an array class.  here's an example using
Borland Pascal 7.0

Type
  float  =  double;

Const
  vMaxDimension      =    65520 div sizeof(float);
      {= See BP7 docs, Language Guide, pg. 30 :  "The maximum permitted size of =}
      {= any structured type in Borland Pascal is 65,520 bytes."  So for double =}
      {= precision floats we've got a max array size of 8190 elements . . .     =}

Type
  TVectorElements  =  array[0..vMaxDimension-1] of float;
  PVectorElements  =  ^TVectorElements;

  PVector   =   ^TVector;
  TVector   =   OBJECT
      Private
        startNDX,
        stopNDX,
        dimension : integer;

        vMemAllocated : word;

        Elements  : PVectorElements;
      Public
        constructor Init(start, stop : integer);
                {= stop must be larger than start =}
        destructor  Done; virtual;

        Procedure PutElement(Index : integer; DataVal : float);
        Function  GetElement (Index : integer) : float;

        Procedure Resize(NewStart, NewStop : integer);
      END;

constructor TVector.Init(start, stop : integer);

  BEGIN   {==TVector.Init==}
    startNDX := start;
    stopNDX := stop;
    dimension := stopNDX - startNDX + 1;
    vMemAllocated := dimension*sizeof(float);
    GetMem(Elements, vMemAllocated);
    FillChar(Elements^, vMemAllocated, 0);
  END;    {==TVector.Init==}

destructor TVector.Done;

  BEGIN   {==TVector.Done==}
    if (vMemAllocated > 0) then
      BEGIN
        FreeMem(Elements, vMemAllocated);
        vMemAllocated := 0;
      END;
    Elements := NIL;
  END;    {==TVector.Done==}

Procedure TVector.PutElement(Index : integer; DataVal : float);
  BEGIN   {==Vector.PutElement==}
    Elements^[ Index - StartNDX ] := DataVal;
  END;    {==Vector.PutElement==}

Function TVector.GetElement(Index : integer) : float;
  BEGIN   {==Vector.GetElement==}
    GetElement := Elements^[ Index - StartNDX ];
  END;    {==Vector.GetElement==}

Procedure TVector.Resize(NewStart, NewStop : integer);
  BEGIN   {==TVector.Resize==}
    Done;
    Init(NewStart, NewStop);
  END;    {==TVector.Resize==}

this compiles okay, but I've never used this particular version
so there may be implementation errors.  surely lots of room for
improvement, but I hope it gets the general idea across...

Mark Vaughan

]-
]-Thanks for any help in advance.
]-
]-Edward Terng
]-MicroForest Systems (Malaysia)
]-edte...@pc.jaring.my
]-

Re:Dynamic Array Size


In article <1996Jun20.012504.27...@arl.mil>,
   Edward Terng <edte...@pc.jaring.my> wrote:

Quote
>I would like to find out is there anyway I can manipulate the size of an

array instead of pre-define it ? Something like :
Quote

>    Ar : Array[n1..n2]

>where n1 and n2 is defined by program during execution.

>It will be even more interesting if I can increase or decrease the elements

in the array.

Type
  TMyStruct = Record
   {stuff for the structure}
  End;

  TMyArr : Array[0..(65520 Div Sizeof(TMyStruct)] Of TMyStruct;
  PMyarr : ^TMyArr;

Var
  arrsize : Integer;

Function MakeArray(num : Integer) : PMyArr;
Var
  theArr : PMyArr;
Begin
  GetMem(theArr, num * Sizeof(TMyStruct));
  arrsize := num;
  MakeArray := theArr;
End;

Procedure KillArray(theArr : PMyArr);
Begin
  FreeMem(theArr, arrsize * Sizeof(TMyStruct));
End;

-----------------------------------------------
Mike Chapin
Powder River
mcha...@vcn.com
http://www.vcn.com/server/netizens/mchapin/first.html
Gillette, WY

Not the end of the earth but you can see it from
there.
-----------------------------------------------

Re:Dynamic Array Size


Quote
> ]-I would like to find out is there anyway I can manipulate the size of an
> ]-array instead of pre-define it ? Something like :
> ]-
> ]-      Ar : Array[n1..n2]
> ]-
> ]-where n1 and n2 is defined by program during execution.
> ]-
> ]-It will be even more interesting if I can increase or decrease the elements
> ]-in the array.

> best (only?) way is to make an array class.  

   Certainly not the _only_ way to do it: the capability's existed in
Turbo Pascal for many releases (prior to OOP), by declaring a maximum
(or minumum) array type, a pointer to it, and allocating Heap memory
specific to the program's execution.  There is some inherent risk in
using a mimimum array type ([0..0]), because you must override Range
Checking to use it.  An example which uses a "maximum array type":

Type DAType = array[0..32760] of integer;
Var  DAPtr  : ^DAType;
...
  GetMem (DAPtr,650*SizeOf(Integer));  { allocate 650 element array }
...
  DAPtr^[13] := -17;               { assign a value to 14th element }
etc.

Re:Dynamic Array Size


Quote
Mike Copeland wrote:
> There is some inherent risk in
> using a mimimum array type ([0..0]), because you must override Range
> Checking to use it.  An example which uses a "maximum array type":

> Type DAType = array[0..32760] of integer;
> Var  DAPtr  : ^DAType;
> ...
>   GetMem (DAPtr,650*SizeOf(Integer));  { allocate 650 element array }
> ...
>   DAPtr^[13] := -17;               { assign a value to 14th element }

No, that is just about as dangerous as using an array[0..0] because any
assignment of the type

    DAPtr^[n]:=x;

in which n>650 will not be trapped by the compiler at run-time and will
likely do very {*word*193} things. I fell into it once and bingo! 50 Meg worth
of lost clusters on my hard disk in the blink of an eye (I thought I had
gone into an infinite loop until I saw my hard light as busy as a busy
beaver and hit the panic button).

Re:Dynamic Array Size


Quote
> > There is some inherent risk in
> > using a mimimum array type ([0..0]), because you must override Range
> > Checking to use it.  An example which uses a "maximum array type":

> > Type DAType = array[0..32760] of integer;
> > Var  DAPtr  : ^DAType;
> > ...
> >   GetMem (DAPtr,650*SizeOf(Integer));  { allocate 650 element array }
> > ...
> >   DAPtr^[13] := -17;               { assign a value to 14th element }

> No, that is just about as dangerous as using an array[0..0] because any
> assignment of the type

>     DAPtr^[n]:=x;

> in which n>650 will not be trapped by the compiler at run-time and will
> likely do very {*word*193} things. I fell into it once and bingo! 50 Meg worth
> of lost clusters on my hard disk in the blink of an eye (I thought I had
> gone into an infinite loop until I saw my hard light as busy as a busy
> beaver and hit the panic button).

   Yes, I neglected to say that, although the compiler won't make you
turn off range Checking if you use a "maximum" array, the programmer
_must_ do virtual range checking within the application code.  In all
cases where this idea of "dynamic arrays" is used, the programmer must be
extra careful, and there's always some risk involved...

Re:Dynamic Array Size


Quote
In article <4qbh5e$...@client3.news.psi.net>, l...@lutz.com writes...
>Sorry, you're in the wrong group/language - neither Pascal nor Fortran
>ever did allow dynamic array allocation in this fashion, although both
>Algol and PL/I do.

Perhaps you should read the Extended Pascal standard (approved in 1989).

The construct asked for is perfectly legal.  

--
John Reagan
DEC Pascal Project Leader
Application Compilers and Environments
Digital Equipment Corporation
rea...@hiyall.enet.dec.com
Disclaimer:  The opinions and statements expressed by me are not
             necessarily those of Digital Equipment Corporation.
--

Re:Dynamic Array Size


Hi all,

Joining the discussion about dynamic array allocation, where many
suggestions have already been made, I think that we all forget the
TCOLLECTION class of ObjectWindows, which actually *is* a dynamically
self-resizing (in increments of 5 or some other number of elements)
array-like type.

Of course, the elements stored in a TCollection must be descendants of some
base object type, and they may be polymorphic, i.e. of different types, as
long as they are derived from that base type.

I believe anyone who is in a project that serious, to demand dynamic array
resizing, should enter the trouble to use such classes.

Greetings,
Votis

-----------------------------------------------------------------------------
Votis Kokavessis
Mathematics teacher & pascal programmer
Thessaloniki, Greece
E-mail address: paratiritis.the.forthnet...@popper.forthnet.gr (votis)
-----------------------------------------------------------------------------

Re:Dynamic Array Size


In article: <1996Jun24.171609.1...@arl.mil>  Votis

Quote
<paratiritis.the.forthnet...@forthnet.gr> writes:

>Hi all,

>Joining the discussion about dynamic array allocation, where many
>suggestions have already been made, I think that we all forget the
>TCOLLECTION class of ObjectWindows,

And DOS programs (Objects.pas is a unit that can be used in programs written for
any of BP's three target platforms).

Quote
> which actually *is* a dynamically
>self-resizing (in increments of 5 or some other number of elements)
>array-like type.

>Of course, the elements stored in a TCollection must be descendants of some
>base object type,

Actually, no they don't. Have a look at the TStringCollection object for
example.

Quote
> and they may be polymorphic, i.e. of different types, as
>long as they are derived from that base type.

>I believe anyone who is in a project that serious, to demand dynamic array
>resizing, should enter the trouble to use such classes.

Agreed. Anyone who isn't using the OOP part of TP is only using half the power
they have at their elbow.

-- Jay

 ---------------------------------------------------------------------------
| Jason Burgon - author of Graphic Vision, TV-Like GUI for 256 Colour SVGA  |
| g...@jayman.demon.co.uk   ftp://SimTel/msdos/turbopas/gv4svga1.zip          |
|                         http://www.en.com/users/grendel/prog/tv_prog.html |
 ---------------------------------------------------------------------------

Re:Dynamic Array Size


Quote
Mike Copeland wrote:
>    Yes, I neglected to say that, although the compiler won't make you
> turn off range Checking if you use a "maximum" array, the programmer
> _must_ do virtual range checking within the application code.  In all
> cases where this idea of "dynamic arrays" is used, the programmer must be
> extra careful, and there's always some risk involved...

Not necessarily if someone goes to the immense trouble of writing
an object along these lines:

aNullArray=array[0..0] of byte;
aNullArrayPtr=^aNullArray;
anArray=object
          lo,hi: longint;
          elementSize,elementType: byte;
          dataPtr: aNullArrayPtr;
          constructor Init(min,max: longint; eType: byte);
          procedure putReal(r: real; location: longint);
          procedure putInteger(i: integer; location: longint);
          (** and so on, with the converse retrieval functions, e.g. *)
          procedure getInteger(var i: integer; location: longint);
          (* etc.... *)
          destructor Free;
end;

I object to having to do that. All that should be taken care of by
the compiler. Humble BASIC allowed it, so there is no excuse
whatsoever.

Other Threads