[comp.lang.pascal] Dynamic arrays in TP5.0

binni@rhi.hi.is (Brynjolfur Thorsson) (07/07/90)

Hi there.

I am trying to use dynamic arrays in my TP5.0 program but am having a hard
time. I want to be able to do things like they are done in C, e.g.

*(x + 10) = 100.5

but I have not found a way to do it. Below is a short program demonstrating
what I want to do, but I have no idea, how to make GetVal and PutVal. If you
have suggestions for me I would appreciate it. I can't believe that this is
impossible in TP.

***************************************************
Program dynamic;

Var
   y : ^Real;
   x : Real;

Begin
   GetMem(y, 10 * SizeOf(Real));
   PutVal(y, 5, 12.34);
   x := GetVal(y, 3);
End.
**************************************************

I hope that this is not to confusing.

Thanks in advance

Brynjolfur.
-- 
************************
Brynjolfur Thorsson                       Internet: binni@rhi.hi.is
Science Institute University of Iceland   UUCP:     ...!mcvax!hafro!rhi!binni

mathrich@mthvax.cs.miami.edu (Rich Winkel) (07/09/90)

In <1831@krafla.rhi.hi.is> binni@rhi.hi.is (Brynjolfur Thorsson) writes:
>I am trying to use dynamic arrays in my TP5.0 program but am having a hard
>time. I want to be able to do things like they are done in C, e.g.

>*(x + 10) = 100.5

>but I have not found a way to do it. Below is a short program demonstrating
>what I want to do, but I have no idea, how to make GetVal and PutVal. If you
>have suggestions for me I would appreciate it. I can't believe that this is
>impossible in TP.

>***************************************************
>Program dynamic;

>Var
>   y : ^array [1..10] of Real;		<----
>   x : Real;

>Begin
>   GetMem(y, SizeOf(^y));		<----
>   ^y[5]:=12.34;			<----
>   x :=^y[3];				<----
>End.

I believe this will work.

Rich

iain@batserver.cs.uq.oz.au (Iain Fogg) (07/10/90)

binni@rhi.hi.is (Brynjolfur Thorsson) writes:

>Hi there.

>I am trying to use dynamic arrays in my TP5.0 program but am having a hard
>time. I want to be able to do things like they are done in C, e.g.

>*(x + 10) = 100.5

>but I have not found a way to do it. Below is a short program demonstrating
>what I want to do, but I have no idea, how to make GetVal and PutVal. If you
>have suggestions for me I would appreciate it. I can't believe that this is
>impossible in TP.

>***************************************************
>Program dynamic;

>Var
>   y : ^Real;
>   x : Real;

>Begin
>   GetMem(y, 10 * SizeOf(Real));
>   PutVal(y, 5, 12.34);
>   x := GetVal(y, 3);
>End.
>**************************************************

Try the following. Can't guarantee it's perfectly correct (haven't got
TP at work), but the idea's right. Obviously, there isn't any range
checking.

  TYPE
    RealPtr = ^Real;

  PROCEDURE PutVal (r_array: RealPtr; pos: Integer; value: Real);
  BEGIN
    r_array := RealPtr (longint (r_array) + (pos - 1) * SizeOf (Real));
    r_array^ := value
  END;
  
  FUNCTION GetVal (r_array: RealPtr; pos: Integer): Real;
  BEGIN
    GetVal := RealPtr (longint (r_array) + (pos - 1) * SizeOf (Real))^
  END;

Hope it helps, Iain.

jgp@fctunl.rccn.pt (Jose Goncalo Pedro) (07/11/90)

In article <1990Jul8.200026.29195@mthvax.cs.miami.edu> mathrich@mthvax.cs.miami.edu (Rich Winkel) writes:

   In <1831@krafla.rhi.hi.is> binni@rhi.hi.is (Brynjolfur Thorsson) writes:

   [ something deleted ]
   >Program dynamic;

   >Var
   >   y : ^array [1..10] of Real;		<----
   >   x : Real;

   >Begin
   >   GetMem(y, SizeOf(^y));		<----
   >   ^y[5]:=12.34;			<----
   >   x :=^y[3];				<----
   >End.

   I believe this will work.

   Rich

It will work, but the size of the array not dinamic. What you probably
want is:

Var y : array [1..LargeNumber] of Real ;

...
	GetMem( y, SizeOfArray * SizeOf(Real) ) ;

	y^[5] := 12.34 ;

	x := y^[3] ;

You should turn off Range Checking if you intend to create arrays of
more than LargeNumber size. The only problem is that there is no range
checking. If you need it, enclose said code in a procedure which
checks array bounds before assigning/reading from the array, and {$R-}
before and {$R+} after (or another letter, I don't remember now)

-jp
--
---
Jose Goncalo Pedro              BITNET/Internet: jgp@fctunl.rccn.pt
 +---------------------------------+             UUCP: jgp@unl.uucp
 |   Departamento de Informatica   +----------------------------------+
 |   Universidade Nova de Lisboa      2825 Monte Caparica, PORTUGAL   |
 +--------------------------------------------------------------------+

lowey@herald.usask.ca (Kevin Lowey) (07/13/90)

From article <1831@krafla.rhi.hi.is>, by binni@rhi.hi.is (Brynjolfur Thorsson):
> Hi there.
> 
> I am trying to use dynamic arrays in my TP5.0 program but am having a hard
> time. I want to be able to do things like they are done in C, e.g.

The following code is VERY Turbo Pascal specific.  I compiled it under 
TP 5.5, but it should work with 4.0 and higher.

There are one main feature of Turbo Pascal 5.5 which facilitates dynamic
arrays, the range checking option {$R-}.  If you turn the range checking 
OFF, then you can index past the end of the array without generating a 
range check error.  This lets you define an array [1..1] of  whatever, 
and then go as high as you want (within the limits of the maximum index 
size).

IMPORTANT: remember the RANGE CHECKING IS TURNED OFF, so you 
MUST make sure that you don't go past the end of the array, otherwise you
can really screw things up.

Here is the program.  It defines the variables, reserves memory for an 
array of size 10, assigns values to the ten items in the array, writes these
values back out again, then frees the memory up.

program test;
{ Written by Kevin Lowey - Copy freely }

Type
  Dummy_array = array [1..1] of real;  
      { with range checking off, you can address as high as you want }

VAR
  Array_Ptr : ^dummy_array;  { For use with GETMEM to allocate array memory }
  i : integer;               { for indexing through loops }

begin
  { Allocate memory for array of size 10 reals }
  { If the SIZEOF(REAL) doesn't work in your TP, create a dummy }
  { REAL_VAR : REAL } variable and then use SIZEOF(REAL_VAR). You }
  { might have to do that in TP 4.0 and earlier }
  getmem (Array_Ptr,sizeof(Real) * 10);
 
  { Assign values to the array }
  for i := 1 to 10 do begin
    {$R-} {turn off range checking }
    array_ptr^[i] := 100.0+i;
    {$R+} {turn range checking on again }
  end;

  { Show that it worked }
  for i := 1 to 10 do begin
    {$R-}
    writeln (i:3,' ',array_ptr^[i]:3:0);
    {$R+}
  end;

  { Free up the memory when we are done }
  freemem (Array_Ptr,sizeof(real) * 10);

end.


- Kevin Lowey

silk@dhw68k.cts.com (Mitch Gorman) (07/13/90)

In article <1990Jul8.200026.29195@mthvax.cs.miami.edu> mathrich@mthvax.cs.miami.edu (Rich Winkel) writes:
>In <1831@krafla.rhi.hi.is> binni@rhi.hi.is (Brynjolfur Thorsson) writes:
>>I am trying to use dynamic arrays in my TP5.0 program but am having a hard
>>time. I want to be able to do things like they are done in C, e.g.
>
>>*(x + 10) = 100.5
>
>>but I have not found a way to do it. Below is a short program demonstrating
>>what I want to do, but I have no idea, how to make GetVal and PutVal. If you
>>have suggestions for me I would appreciate it. I can't believe that this is
>>impossible in TP.
>
>>***************************************************
>>Program dynamic;
>
>>Var
>>   y : ^array [1..10] of Real;		<----
>>   x : Real;
>
>>Begin
>>   GetMem(y, SizeOf(^y));		<----
>>   ^y[5]:=12.34;			<----
>>   x :=^y[3];				<----
>>End.
>
>I believe this will work.
>
>Rich

	Yes, this method will work, but it misses the point of what Brynjolfur
wants to do.  Of course, there's nothing wrong with this method, but it seems
to me that the idea is to explicitly declare an array normally, not declare
a pointer to an array.

	Those functions (Putval and Getval) could be made to work inelegantly
by simply passing the address of the array (which happens automagically, of
course), and the size of the data elements which constitute the array.  This
way, details of how to get to the desired element are hidden (gotta love this
abstraction crap! :^), and it has the advantage of not requiring a special
declaration for the array you plan to access by this method (viz *(array + n)).

	Those functions would simply add the multiple of the index into the
array and the size of the elements to the base address of the array.  It's not
even necessary to force the issue by passing "&array", since that can be done
inside the routines (again, for transparency).

	Of course, the truth is that I'm babbling off the top of my head, and
haven't tested this garbage I'm spouting, so perhaps it's time for me to shut
up now.  :^)


_______________________________________________________________________________
	Mitch Gorman		Internet:  silk@dhw68k.cts.com
				uucp:  ...{spsd,zardoz,felix}!dhw68k!silk
-------------------------------------------------------------------------------
"Never seen the same face twice, never walked the same way;
 	And the little love that I have known I keep to myself."
		- Genesis, "Say It's Alright, Joe", _And Then There Were Three_
_______________________________________________________________________________

milne@ics.uci.edu (Alastair Milne) (07/14/90)

In <1990Jul8.200026.29195@mthvax.cs.miami.edu> mathrich@mthvax.cs.miami.edu (Rich Winkel) writes:

>>Begin
>>   GetMem(y, SizeOf(^y));		<----

     OOOPS.  SIZEOF(Y), not of the pointer to it.  SIZEOF(^Y) will return
     a grand 4 bytes, no matter to what it's pointing.

>>   ^y[5]:=12.34;			<----
>>   x :=^y[3];				<----
>>End.

    Close.  Indirect through the pointer *after* referring to it (ie. Y^)
    not before (^Y) and you'll be fine.  The ^Y form is for the declaration,
    saying implicitly "redirect to reach the following type."


    Alastair Milne