[comp.lang.pascal] need dynamic array on heap

John G. Spragge <SPRAGGEJ@QUCDN.QueensU.CA> (04/13/91)

In article <1991Apr12.234843.9031@ux1.cso.uiuc.edu>, amead@s.psych.uiuc.edu
(alan mead) says:
>
>I want to put aside a chunk of the heap and then index it by byte like
>an array of byte.  I could just declare it as some type like
>'array[1..64000] of byte', but I want to use GetMem so that the array will
>really be dynamic (I don't want to use 64K each time).
>
>So, I'm trying this:
>
>program Test;
>  type
>    C_arrayType = array[1..1] of byte;
>  var
>    Buff : ^C_arrayType;
>  begin
>    GetMem( Buff,1000 );
>    Buff[1]^ := 2;
>  end.
>
>But I get
>
>  Buff[1]^ := 2;
>      ^ Invalid qualifier
>
>so does anyone know, is this sort of thing possible?  Can you do this
>easily in C?

You're putting the pointer in the wrong place. Buff is a
pointer; what you're trying to say is (in English)

   reference the array pointed at by pointer variable BUFF
   at location (n), and assign the number 10.

translated into Pascal, this becomes

   buff^ [1] := 10;

Thus:


buff (Pascal variable) = [o]
                          |
points at (buff^)         V
                         +------------------------------------ \
an array on the heap     |  |  |  |  |  |  |  |  |  |  |  |    /
                         +-------------------------------------\
                           1  2  3  4  5  6  7  8  9 10 11
                                                     ^
                                                     |
so that:     buff^ [10] -----------------------------+

disclaimer: Queen's University supplies me with computer services, not
            my opinions.

John G. Spragge

amead@s.psych.uiuc.edu (alan mead) (04/13/91)

I want to put aside a chunk of the heap and then index it by byte like 
an array of byte.  I could just declare it as some type like 
'array[1..64000] of byte', but I want to use GetMem so that the array will
really be dynamic (I don't want to use 64K each time).

So, I'm trying this:

program Test;
  type
    C_arrayType = array[1..1] of byte;
  var
    Buff : ^C_arrayType;
  begin
    GetMem( Buff,1000 );
    Buff[1]^ := 2;
  end.

But I get 

  Buff[1]^ := 2;
      ^ Invalid qualifier

so does anyone know, is this sort of thing possible?  Can you do this
easily in C?

Thanks,

-alan mead : amead@s.psych.uiuc.edu

steve@cad0.arch.unsw.oz.au (Stephen Peter) (04/13/91)

In article <1991Apr12.234843.9031@ux1.cso.uiuc.edu> amead@s.psych.uiuc.edu (alan mead) writes:
>I want to put aside a chunk of the heap and then index it by byte like 
.
.
.
>But I get 
>
>  Buff[1]^ := 2;
>      ^ Invalid qualifier
>
>so does anyone know, is this sort of thing possible?  Can you do this
>easily in C?
>

Try addressing the structure as a pointer to an array:

   Buff^[1] := 2;

which should work.

>-alan mead : amead@s.psych.uiuc.edu

Stephen.
--
 _--_|\                                           steve@cad0.arch.unsw.oz.au
/      \    Stephen Peter                 or  steve@keystone.arch.unsw.oz.au
\_.--._/<-------------------------------------------------------------------
      v     School of Architecture, University of New South Wales, Australia

nmouawad@watmath.waterloo.edu (Naji Mouawad) (04/15/91)

In article <1991Apr12.234843.9031@ux1.cso.uiuc.edu> amead@s.psych.uiuc.edu (alan mead) writes:
>I want to put aside a chunk of the heap and then index it by byte like 
>an array of byte.  I could just declare it as some type like 
>'array[1..64000] of byte', but I want to use GetMem so that the array will
>really be dynamic (I don't want to use 64K each time).
>
>So, I'm trying this:
>
>program Test;
>  type
>    C_arrayType = array[1..1] of byte;
>  var
>    Buff : ^C_arrayType;
>  begin
>    GetMem( Buff,1000 );
>    Buff[1]^ := 2;
>  end.
>
>But I get 
>
>  Buff[1]^ := 2;
>      ^ Invalid qualifier
>

  try Buff^[1] := 2;

You are using a pointer to an array. Thus, you point first to the
array and then you index it.

>Thanks,
>
>-alan mead : amead@s.psych.uiuc.edu

--Naji.
-- 
     -------------------------------------------------------------------
    | Naji Mouawad  |          nmouawad@watmath.waterloo.edu            |
    |  University   |---------------------------------------------------|
    | Of Waterloo   |   "The Stranger in us is our most familiar Self"  |

kushmer@bnlux1.bnl.gov (christopher kushmerick) (04/15/91)

In article <1991Apr14.205511.11509@watmath.waterloo.edu> nmouawad@watmath.waterloo.edu (Naji Mouawad) writes:
>In article <1991Apr12.234843.9031@ux1.cso.uiuc.edu> amead@s.psych.uiuc.edu (alan mead) writes:
>>I want to put aside a chunk of the heap and then index it by byte like 
>>  type
>>    C_arrayType = array[1..1] of byte;
>>  var
>>    Buff : ^C_arrayType;
>>  begin
>>    GetMem( Buff,1000 );
>>    Buff[1]^ := 2;
>>  end.
>  try Buff^[1] := 2;
>
But in general you'll need to do this:


i := n;
buff^[i] := m

where n is the index to receive the value m

This is because if you try, for example, buff^[10]=1 then
the compiler will catch the out of range error.

You'll still need to defeat _run time_ range checking with {$R-}
but you can not defeat compile time range checking...


-Chris

-- 
Chris Kushmerick                                 kciremhsuK sirhC
kushmer@bnlux1.bnl.gov    <===Try this one first
kushmerick@pofvax.sunysb.edu 

amead@s.psych.uiuc.edu (alan mead) (04/15/91)

kushmer@bnlux1.bnl.gov (christopher kushmerick) writes:

>In article <1991Apr14.205511.11509@watmath.waterloo.edu> nmouawad@watmath.waterloo.edu (Naji Mouawad) writes:
>>In article <1991Apr12.234843.9031@ux1.cso.uiuc.edu> amead@s.psych.uiuc.edu (alan mead) writes:
>>>I want to put aside a chunk of the heap and then index it by byte like 
>>>  type
>>>    C_arrayType = array[1..1] of byte;
>>>  var
>>>    Buff : ^C_arrayType;
>>>  begin
>>>    GetMem( Buff,1000 );
>>>    Buff[1]^ := 2;
>>>  end.
>>  try Buff^[1] := 2;
>>
>But in general you'll need to do this:


>i := n;
>buff^[i] := m

>where n is the index to receive the value m

>This is because if you try, for example, buff^[10]=1 then
>the compiler will catch the out of range error.

>You'll still need to defeat _run time_ range checking with {$R-}
>but you can not defeat compile time range checking...


>-Chris

Yes.  Thanks all who have pointed out my mistake.  I have decided tha
there is no good reason not to declare the type as 1..65535, so I won't
have any run time error problems.

-alan

>-- 
>Chris Kushmerick                                 kciremhsuK sirhC
>kushmer@bnlux1.bnl.gov    <===Try this one first
>kushmerick@pofvax.sunysb.edu 

defaria@hpcupt3.cup.hp.com (Andy DeFaria) (04/15/91)

>/ hpcupt3:comp.lang.pascal / amead@s.psych.uiuc.edu (alan mead) /  3:48 pm  Apr 12, 1991 /
>I want to put aside a chunk of the heap and then index it by byte like 
>an array of byte.  I could just declare it as some type like 
>'array[1..64000] of byte', but I want to use GetMem so that the array will
>really be dynamic (I don't want to use 64K each time).
>
>So, I'm trying this:
>
>program Test;
>  type
>    C_arrayType = array[1..1] of byte;
>  var
>    Buff : ^C_arrayType;
>  begin
>    GetMem( Buff,1000 );
>    Buff[1]^ := 2;
>  end.
>
>But I get 
>
>  Buff[1]^ := 2;
>      ^ Invalid qualifier
>
>so does anyone know, is this sort of thing possible?  Can you do this
>easily in C?

Change the TYPE to

  type
    C_arrayType = array[1..64000] of byte;

After all a type doesn't allocate any memory, it is the getmem that will
allocate the memory on the heap.  When you say Buff[1] TP knows that they
array only goes 1..1 so you get a compiler error.

jerry@gumby.Altos.COM (Jerry Gardner) (04/17/91)

In article <1991Apr12.234843.9031@ux1.cso.uiuc.edu> amead@s.psych.uiuc.edu (alan mead) writes:
>I want to put aside a chunk of the heap and then index it by byte like 
>an array of byte.  I could just declare it as some type like 
>'array[1..64000] of byte', but I want to use GetMem so that the array will
>really be dynamic (I don't want to use 64K each time).
>
>  Buff[1]^ := 2;
>      ^ Invalid qualifier
>
>so does anyone know, is this sort of thing possible?  Can you do this
>easily in C?


This is very easy in C:

main()

{

	char	*buff;


	buff = (char *)malloc(1000);

	buff[0] = 2;

}



-- 
Jerry Gardner, NJ6A					Altos Computer Systems
UUCP: {sun|pyramid|sco|amdahl|uunet}!altos!jerry	2641 Orchard Parkway
Internet: jerry@altos.com				San Jose, CA  95134
Help stamp out vi in our lifetime.                      (408) 432-6200

bobb@vice.ICO.TEK.COM (Bob Beauchaine) (04/17/91)

In article <4816@gumby.Altos.COM> jerry@altos.COM (Jerry Gardner) writes:
>In article <1991Apr12.234843.9031@ux1.cso.uiuc.edu> amead@s.psych.uiuc.edu (alan mead) writes:
>>I want to put aside a chunk of the heap and then index it by byte like 
>>an array of byte.  I could just declare it as some type like 
>>'array[1..64000] of byte', but I want to use GetMem so that the array will
>>really be dynamic (I don't want to use 64K each time).
>>

  I haven't been following this thread very closely, so this may all
  have been suggested, but I'm bored...

  Have you tried a typecast for true dynamic allocation?

  type byte_buf = array[1..64000] of byte;
       byte_buf_ptr = ^byte_buf;

  var  buffer : pointer;

  .
  .
  .
  getmem(buffer,somesize); { Allocate only as many bytes as you need }
  byte_buf_ptr(buffer)^[2] := somevalue;
  .
  .
  .


  This allows you to allocate on the fly.  It also has it's own caveats.
  You'd better be damn sure you never write to an array member outside
  of the actual range of subscripts allocated by your getmem() call, 
  since the compiler can't do range checking on the type cast.  Otherwise,
  I use techniques like this all the time when I don't know what kind
  of data I'm dealing with until run time.

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ 

Bob Beauchaine bobb@vice.ICO.TEK.COM 

C: The language that combines the power of assembly language with the 
   flexibility of assembly language.

John G. Spragge <SPRAGGEJ@QUCDN.QueensU.CA> (04/18/91)

In article <7294@vice.ICO.TEK.COM>, bobb@vice.ICO.TEK.COM (Bob Beauchaine) says:
>
>  type byte_buf = array[1..64000] of byte;
>       byte_buf_ptr = ^byte_buf;
>
>  var  buffer : pointer;
>  .
>  .
>  getmem(buffer,somesize); { Allocate only as many bytes as you need }
>  byte_buf_ptr(buffer)^[2] := somevalue;

Actually, since GETMEM takes ANY pointer type, you don't need
the typecast. You don't have to allocate enough memory for the
structure you're loading; you just have to be sure your code
will manage dynamic structures correctly.

disclaimer: Queen's University supplies me with computer services, not
            my opinions.

John G. Spragge

bobb@vice.ICO.TEK.COM (Bob Beauchaine) (04/18/91)

In article <91107.174405SPRAGGEJ@QUCDN.QueensU.CA> SPRAGGEJ@QUCDN.QueensU.CA (John G. Spragge) writes:
>In article <7294@vice.ICO.TEK.COM>, bobb@vice.ICO.TEK.COM (Bob Beauchaine) says:
>>
>>  type byte_buf = array[1..64000] of byte;
>>       byte_buf_ptr = ^byte_buf;
>>
>>  var  buffer : pointer;
>>  .
>>  .
>>  getmem(buffer,somesize); { Allocate only as many bytes as you need }
>>  byte_buf_ptr(buffer)^[2] := somevalue;
>
>Actually, since GETMEM takes ANY pointer type, you don't need
>the typecast. You don't have to allocate enough memory for the
>structure you're loading; you just have to be sure your code
>will manage dynamic structures correctly.
>

  You most certainly do need the typecast.  Notice the getmem call
  does not use the typecast; it's the reference to the pointer
  as a pointer to an array of bytes that requires the typecast.
  Guess you weren't reading too close :).

  As I said, I use this method frequently.  You don't get a free 
  lunch; bypassing Pascal's strong type checking takes a little
  more work.



/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ 

Bob Beauchaine bobb@vice.ICO.TEK.COM 

C: The language that combines the power of assembly language with the 
   flexibility of assembly language.

John G. Spragge <SPRAGGEJ@QUCDN.QueensU.CA> (04/20/91)

In article <7309@vice.ICO.TEK.COM>, bobb@vice.ICO.TEK.COM (Bob Beauchaine) says:
>
>>>
>>>  type byte_buf = array[1..64000] of byte;
>>>       byte_buf_ptr = ^byte_buf;
>>>
>>>  var  buffer : pointer;
>>>  .
>>>  .
>>>  getmem(buffer,somesize); { Allocate only as many bytes as you need }
>>>  byte_buf_ptr(buffer)^[2] := somevalue;
>>
>>Actually, since GETMEM takes ANY pointer type, you don't need
>>the typecast. You don't have to allocate enough memory for the
>>structure you're loading; you just have to be sure your code
>>will manage dynamic structures correctly.
>>
>
>  You most certainly do need the typecast.  Notice the getmem call
>  does not use the typecast; it's the reference to the pointer
>  as a pointer to an array of bytes that requires the typecast.

The way I do it is:

TYPE
   pflexb  =   ^flexb;
   flexb   =   ARRAY [1 .. 64000] OF CHAR;

VAR
   fb      :   pflexb;
   c       :   INTEGER;

BEGIN
   GETMEM (fb, 2000);
   FOR c := 1 TO 2000 DO
       fb [c] := 'm';
END.

I think yo'll find that works well enough, withot requiring a
typecast. To anyone who thoght I was saying yo don't need a
typecast the dereference a generic pointer, I apologize.

disclaimer: Queen's University supplies me with computer services, not
            my opinions.

John G. Spragge

Kai_Henningsen@ms.maus.de (Kai Henningsen) (04/22/91)

JG>In article <1991Apr12.234843.9031@ux1.cso.uiuc.edu> amead@s.psych.uiuc.edu (
JG>>I want to put aside a chunk of the heap and then index it by byte like
JG>>an array of byte.  I could just declare it as some type like
JG>>'array[1..64000] of byte', but I want to use GetMem so that the array will
JG>>really be dynamic (I don't want to use 64K each time).
JG>>
JG>>  Buff[1]^ := 2;
JG>>      ^ Invalid qualifier
JG>>
JG>>so does anyone know, is this sort of thing possible?  Can you do this
JG>>easily in C?

Of course it's possible, even in TP. Do exactly what you would do with new,
only use GetMem:

type tBuff = array [0 .. maxit] of byte;
var Buff: ^tBuff;
begin
  GetMem(Buff, 1864);
  Buf^[17] := 42;

...

I do that all the time ...

MfG Kai

Kai_Henningsen@ms.maus.de (Kai Henningsen) (04/23/91)

BB>>>  type byte_buf = array[1..64000] of byte;
BB>>>       byte_buf_ptr = ^byte_buf;
BB>>>
BB>>>  var  buffer : pointer;
BB>>>  .
BB>>>  .
BB>>>  getmem(buffer,somesize); { Allocate only as many bytes as you need }
BB>>>  byte_buf_ptr(buffer)^[2] := somevalue;

BB>  You most certainly do need the typecast.  Notice the getmem call
BB>  does not use the typecast; it's the reference to the pointer
BB>  as a pointer to an array of bytes that requires the typecast.
BB>  Guess you weren't reading too close :).
BB>
BB>  As I said, I use this method frequently.  You don't get a free
BB>  lunch; bypassing Pascal's strong type checking takes a little
BB>  more work.

You most certainly don't need the type cast, you need a correct type
definition. As I already said, declare buffer as pointer to an array, not as
simply "pointer"; then, you can leave any casts out. I do it all the time.

MfG Kai

bobb@vice.ICO.TEK.COM (Bob Beauchaine) (04/26/91)

In article <13834@ms.maus.de> Kai_Henningsen@ms.maus.de (Kai Henningsen) writes:
>
>
>You most certainly don't need the type cast, you need a correct type
>definition. As I already said, declare buffer as pointer to an array, not as
>simply "pointer"; then, you can leave any casts out. I do it all the time.
>
 *AS MY EXAMPLE WAS WRITTEN*, a typecast was necessary.  True, there is 
 more than one way to skin the cat, but the original post implied that
 a typecast in my example was not necessary, which is blatantly not the
 case.

 As for correctness of the type declaration, let's not make judgements
 about code which is syntactically proper but doesn't meet your 
 definition of correctness.

/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\ 

Bob Beauchaine bobb@vice.ICO.TEK.COM 

C: The language that combines the power of assembly language with the 
   flexibility of assembly language.