Board index » delphi » How to create dynamic arrays of records?

How to create dynamic arrays of records?

This question is so simple that the title says it all.  How do I create
arrays on the heap at run-time without knowing the size of the array at
compile time?  Is there a way to reference the elements in a standard
array-like fashion rather than calculating the byte offset into the
array space?  All of the examples that I see in books define a type of a
array of an array of a certain static size then allocate space for such
a type with a pointer to that type set to the allocated space.  This
requires compile time knowledge of the array size.  I need to declare
the size at run-time and be able to allocate and deallocate many arrays
of types or records or two dimensioned arrays.

Thanks for any responses

Dave Brown
Beaverton OR

 

Re:How to create dynamic arrays of records?


This question is so simple that the title says it all.  How do I create
arrays on the heap at run-time without knowing the size of the array at
compile time?  Is there a way to reference the elements in a standard
array-like fashion rather than calculating the byte offset into the
array space?  All of the examples that I see in books define a type of a
array of an array of a certain static size then allocate space for such
a type with a pointer to that type set to the allocated space.  This
requires compile time knowledge of the array size.  I need to declare
the size at run-time and be able to allocate and deallocate many arrays
of types or records or two dimensioned arrays.

Thanks for any responses

Dave Brown
Beaverton OR

Re:How to create dynamic arrays of records?


This question is so simple that the title says it all.  How do I create
arrays on the heap at run-time without knowing the size of the array at
compile time?  Is there a way to reference the elements in a standard
array-like fashion rather than calculating the byte offset into the
array space?  All of the examples that I see in books define a type of a
array of an array of a certain static size then allocate space for such
a type with a pointer to that type set to the allocated space.  This
requires compile time knowledge of the array size.  I need to declare
the size at run-time and be able to allocate and deallocate many arrays
of types or records or two dimensioned arrays.

Thanks for any responses

Dave Brown
Beaverton OR

Re:How to create dynamic arrays of records?


Quote
On Thu, 18 Dec 1997 23:24:19 -0800, Dave Brown <D...@Brown.org> wrote:
>This question is so simple that the title says it all.  How do I create
>arrays on the heap at run-time without knowing the size of the array at
>compile time?  Is there a way to reference the elements in a standard
>array-like fashion rather than calculating the byte offset into the
>array space?  All of the examples that I see in books define a type of a
>array of an array of a certain static size then allocate space for such
>a type with a pointer to that type set to the allocated space.  This
>requires compile time knowledge of the array size.  I need to declare
>the size at run-time and be able to allocate and deallocate many arrays
>of types or records or two dimensioned arrays.

>Thanks for any responses

>Dave Brown
>Beaverton OR

The trick is to declare an array type of a certain static size, but
then to allocate only part of it:
type
   TMyRecord =
      record
       {... }
      end;

const
      MaxSize = $fff0 div sizeof(TMyRecord);
{ maximum size for 16-bitDelphi }

type
     PMyArray = ^TMyArray;
     TMyArray = array[0..MaxSize - 1] of TMyRecord;

var
     MyArrayPtr: PMyArray;

begin
    { dynamically allocate an array, 0 < SomeNumber  <= MaxSize }
    GetMem(MyArrayPtr, SomeNumber * sizeof(TMyRecord));
{ now you have an actual array of SomeNumber elements; note that YOU
have to do the range checking, the compiler will think there are
MaxSize elements! }

{ using the array: }
   MyArrayPtr^[12] :=  SomeVariable;
   SomeVariable := MyArrayPtr^[3]

{ deallocating }
   FreeMem(MyArrayPtr, SomeNumber * sizeof(TMyRecord));
{ the last parameter can be left out in Delphi 2+ }

end.

This is the basic trick. For two-dimensional arrays, you would have to
use an array of pointers (e.g. PMyArray types) for the first
dimension. Hope you can deduce it from here.

hth
David
------------------
David A. Schweizer

iec ProGAMMA, The Netherlands
d.a.schweizer[OK, i don't want any more spam]gamma.rug.nl
guess where the '@' goes ?

Re:How to create dynamic arrays of records?


Quote
David A. Schweizer wrote:

> The trick is to declare an array type of a certain static size, but
> then to allocate only part of it:
> type
>    TMyRecord =
>       record
>        {... }
>       end;

> const
>       MaxSize = $fff0 div sizeof(TMyRecord);
> { maximum size for 16-bitDelphi }

> type
>      PMyArray = ^TMyArray;
>      TMyArray = array[0..MaxSize - 1] of TMyRecord;

Personally, I prefer to define the array as:

        TMyArray = array[0..0] of TMyRecord;

and turn off range checking on the compiler options page.  The eliminates the
potential for ambiguity on the actual size of the array.  For instance,
high(MyArray^) = MaxSize in the original which might look plausable, whereas
my def yields 0 which is clearly wrong.

Bob Lee

Re:How to create dynamic arrays of records?


Quote
Dave Brown wrote:

> This question is so simple that the title says it all.  How do I create
> arrays on the heap at run-time without knowing the size of the array at
> compile time?  Is there a way to reference the elements in a standard
> array-like fashion rather than calculating the byte offset into the
> array space?  All of the examples that I see in books define a type of a
> array of an array of a certain static size then allocate space for such
> a type with a pointer to that type set to the allocated space.  This
> requires compile time knowledge of the array size.  I need to declare
> the size at run-time and be able to allocate and deallocate many arrays
> of types or records or two dimensioned arrays.

> Thanks for any responses

I can't stand the examples that declare an array of a static size ('That
should be large enough.') at compile time. It's ducking the issue.

Delphi isn't very nice about pointer arithmetic, but a good wrapper
class can hide all the details. I haven't had any speed problems with my
class.

I have a TDoublePointArray class which automatically allocates
TDoublePoint records as defined below:

type
  TDoublePoint = record
    X, Y: Double;
  end;

It has an indexed Points[] property that returns any point in the array.
Is that what you want?

Give me an email and I'll send you the source. It even works in (*gasp*)
16-bit Windows using the global heap.

Cheers,

Dave
da...@cfxc.com

Re:How to create dynamic arrays of records?


Quote
Dave Brown wrote in message <67d7cj$...@bgtnsc03.worldnet.att.net>...
>This question is so simple that the title says it all.  How do I create
>arrays on the heap at run-time without knowing the size of the array at
>compile time?

The easiest answer: use the built-in TList.

For matrices & the like, check out our Matrix Math Toolkit
at our site...
--
Grace + Peace | Peter N Roth | Engineering Objects Int'l
Author: "Creating a Robust Type-Safe TList", Delphi Developer Oct 97
Visit our website at http://www.inconresearch.com/eoi
"On the internet, nobody knows you're a dog." - P Steiner

Re:How to create dynamic arrays of records?


The answer is as simple as the question:

Look in your Delphi Help file for the following topics:

    varArrayCreate function  { This allows you to create a variant size
array of any size }

    varArrayReDim function  { This allows you to resize a previously created
variant array }

The beauty is, since they are functions that return pointers to a variant
type, you can pass it the arguments as variables.  Hence, run-time definable
arrays!!!!  AN EXAMPLE:

procedure VarArrayExample;
var
  Arr1 : Variant;
  NumFields : Integer;
begin
    NumFields := 10;
    Arr1 := VarArrayCreate( [0, NumFields], varVariant );

    NumFields := 100;
    VarArrayReDim( Arr1, NumFields );
end;

Quote
Dave Brown wrote in message <67d7cj$...@bgtnsc03.worldnet.att.net>...
>This question is so simple that the title says it all.  How do I create
>arrays on the heap at run-time without knowing the size of the array at
>compile time?  Is there a way to reference the elements in a standard
>array-like fashion rather than calculating the byte offset into the
>array space?  All of the examples that I see in books define a type of a
>array of an array of a certain static size then allocate space for such
>a type with a pointer to that type set to the allocated space.  This
>requires compile time knowledge of the array size.  I need to declare
>the size at run-time and be able to allocate and deallocate many arrays
>of types or records or two dimensioned arrays.

>Thanks for any responses

>Dave Brown
>Beaverton OR

Re:How to create dynamic arrays of records?


Quote
Enrique Polo wrote in message <67eknv$...@nrtphc11.bnr.ca>...
>The answer is as simple as the question:

>Look in your Delphi Help file for the following topics:

>    varArrayCreate function  { This allows you to create a variant size
>array of any size }

>    varArrayReDim function  { This allows you to resize a previously
created
>variant array }

>The beauty is, since they are functions that return pointers to a variant
>type, you can pass it the arguments as variables.  Hence, run-time
definable
>arrays!!!!  AN EXAMPLE:

I recommend NOT using varArray. They are mainly for
"interface compatibility", and trade away type-safety
for slower code. Better to use a TList or a derivative thereof.
--
Grace + Peace | Peter N Roth | Engineering Objects Int'l
Author: "Creating a Robust Type-Safe TList", Delphi Developer Oct 97
Visit our website at http://www.inconresearch.com/eoi
"On the internet, nobody knows you're a dog." - P Steiner

Re:How to create dynamic arrays of records?


How about an array of a union of pointers that are allocated as needed.  The
pointers can be arrays.  The standard C++ solution is based on overloading
the array index operator.  A metaclass that manages arrays of arrays uses
the same technique so a [][] calls minor * major::operator [] and datatype
minor::operator [] is called subsequently.

    Ashok Thirumurthi
    73060.3...@compuserve.com

Quote
Dave Brown wrote:
> This question is so simple that the title says it all.  How do I create
> arrays on the heap at run-time without knowing the size of the array at
> compile time?  Is there a way to reference the elements in a standard
> array-like fashion rather than calculating the byte offset into the
> array space?  All of the examples that I see in books define a type of a
> array of an array of a certain static size then allocate space for such
> a type with a pointer to that type set to the allocated space.  This
> requires compile time knowledge of the array size.  I need to declare
> the size at run-time and be able to allocate and deallocate many arrays
> of types or records or two dimensioned arrays.

> Thanks for any responses

> Dave Brown
> Beaverton OR

Re:How to create dynamic arrays of records?


In article <34A02546.657D9...@compuserve.com> Ashok Thirumurthi <73060.3077.fooled....@compuserve.com> writes:

Quote
>How about an array of a union of pointers that are allocated as needed.  The
>pointers can be arrays.  The standard C++ solution is based on overloading
>the array index operator.  A metaclass that manages arrays of arrays uses
>the same technique so a [][] calls minor * major::operator [] and datatype
>minor::operator [] is called subsequently.
>    Ashok Thirumurthi
>    73060.3...@compuserve.com
>Dave Brown wrote:
>> This question is so simple that the title says it all.  How do I create
>> arrays on the heap at run-time without knowing the size of the array at
>> compile time?  Is there a way to reference the elements in a standard
>> array-like fashion rather than calculating the byte offset into the
>> array space?  All of the examples that I see in books define a type of a
>> array of an array of a certain static size then allocate space for such
>> a type with a pointer to that type set to the allocated space.  This
>> requires compile time knowledge of the array size.  I need to declare
>> the size at run-time and be able to allocate and deallocate many arrays
>> of types or records or two dimensioned arrays.

What you should do in Delphi, Dave, is to set up (or buy or download) a
container class that will support a multidimensional array.  Each of the
records is a separate object, and the container-class provides access to them.

For example, the SysTools package (Turbopower Software) provides about four
different types of large-matrix containers.  You can also construct one of
your own.

For example, one class that I built, using SysTools to provide the underlying
support, accepts a list of arguments as a parameter, then hashes this into a
key that's used to look up the entry in a hash-dictionary.  This was done for
an application with a very sparse matrix.

Notice that the container-class presents the *behavior* of an array without
necessarily using a contiguous block of memory -- even of pointers -- to do
it.  The caller doesn't know or care how the class works.

And notice also that I referred, twice, to buying or downloading something
that already existed -- instead of "rolling your own."  There's just so much
good stuff out there now that's either free or that costs the same as two
hours of your development time.  :-/

Re:How to create dynamic arrays of records?


Quote
Sundial Services wrote:
> >> This question is so simple that the title says it all.  How do I create
> >> arrays on the heap at run-time without knowing the size of the array at
> >> compile time?  Is there a way to reference the elements in a standard
> >> array-like fashion rather than calculating the byte offset into the
> >> array space?  All of the examples that I see in books define a type of a
> >> array of an array of a certain static size then allocate space for such
> >> a type with a pointer to that type set to the allocated space.  This
> >> requires compile time knowledge of the array size.  I need to declare
> >> the size at run-time and be able to allocate and deallocate many arrays
> >> of types or records or two dimensioned arrays.

> What you should do in Delphi, Dave, is to set up (or buy or download) a
> container class that will support a multidimensional array.  Each of the
> records is a separate object, and the container-class provides access to them.

If you are comfortable with the Delphi VCL then maybe a solution would
be to
"wrap" (or just use "as is") the TList. TLists are very good at storing
generic pointers to data. I use them all the time. It sure beats having
to
come up with another container or reinvent the wheel as it were.

Other Threads