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 ?
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
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
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
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;
Dave Brown wrote in message <67d7cj$k...@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
>
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.
Ashok Thirumurthi
73060...@compuserve.com
> Ashok Thirumurthi
> 73060...@compuserve.com
>Dave Brown wrote:
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. :-/
> >> 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.