Board index » delphi » dynamic arrays inside records

dynamic arrays inside records

Can someone help me with making a few arrays inside a record dynamic?
The size of the arrays aren't known until the object is read in from a
file,and the size is what I want to use to dimension those arrays.  As
far as I know, pascal won't allow you to use one of the record fields
(numeric of course) to dimension the arrays.  So what I did instead is
declare the arrays from 0..MAX, where MAX is the biggest array I could
declare before hitting the 64k limit. That works fine, but it's a total
waste of memory when my objects are really small.

Using my record below, if I were to read in a small object, like a cube,
where total_verts = 8 and total_faces = 12, then I would only need two
arrays that range from 0..7 (for vert and vert_norm) and two more that
range from 0..11 (for face and face_norm)...but I can't do that,
*instead* I have something like 0..800 (for vert and vert_norm) and
0..1000 (for face and face_norm).  As you can see, it's a total WASTE of
memory, plus I can only have one 3d object declared since the data
segment is limited to 64k.

Type
    vect_type = record
        x, y, z : real;
    end;

    face_type = record
        p1, p2, p3 : integer;
        z_avg : real;
    end;

    _3D_Object_type = record
        name        : string[15];
        total_verts : integer;
        total_faces : integer;
        vert        : array[0..total_verts] of vect_type;
        face        : array[0..total_faces] of face_type;
        face_norm   : array[0..total_faces] of vect_type;
        vert_norm   : array[0..total_verts] of vect_type;
    end;

(Note: of course this wouldn't work, it's just the way I'd like to be
able to dimmension the arrays <g>)

Anyone care to help?....hope I didn't lose anyone in the confusing
explaination =)  If possible, please reply to me via e-mail at
valaca...@usa.net, thanks a bunch!

 

Re:dynamic arrays inside records


Quote
Valacar <valaca...@usa.net> wrote:
>Can someone help me with making a few arrays inside a record dynamic?
>The size of the arrays aren't known until the object is read in from a
>file,and the size is what I want to use to dimension those arrays.

[snip ... ]

From your example, I assume you want a non-OOP solution.

First, let's redefine your records so that we can have pointers to the
object and to each of the arrays.  This will allow us to store the object
on the heap (which is really the only place for dynamic structures), and
to dynamically reference each array.

In the following, prefix t=type-declaration, tp=type-pointer,
tr=type-record, n=number-of-something

TYPE trVert = record
        x,y,z: Real;
     End;
     tpVert = ^tVert;
     tVert  = Array[0..3500] of trVert;

     trFace = record
        p1, p2, p3 : integer;
        z_avg : real;
     end;
     tpFace = ^tFace;
     tFace  = Array[0..3500] of trFace;

TYPE tp3Dobj = ^t3Dobj;
     t3Dobj  = RECORD
        Vert    : tpVert;
        Face    : tpFace;
        FaceNorm: tpFace;
        VertNorm: tpVert;
        MemSize : Word;

        nVert: Word;
        nFace: Word;
        Name : String;
     End;

The above t3Dobj defines the memory image of the object. The disk image of
an object consists of:

Size     : word;                 { size of everything except this word }
nVert    : Word;                 { Number of vert elements             }
nFace    : Word;                 { Number of face elements             }
Name     : String[Length(Name)]; { Exact length Pascal style string    }
Vert     : Array of trVert;      { tVert array of nVert elements       }
Face     : Array of trFace;      { tFace array of nFace elements       }
FaceNorm : Array of trFace;      { tFace array of nFace elements       }
VertNorm : Array of trVert;      { tVert array of nVert elements       }

The following function provides an example of how to read an
object from disk:

FUNCTION GetObj(VAR F: File; Offset: Longint): tp3Dobj;
{ ----------------------------------------------------- }
{ File is assumed to be opended w/ recsize 1            }
{ ----------------------------------------------------- }
VAR obj: tp3Dobj;
    i,j: Word;

BEGIN
  Seek(F, Offset);
  BlockRead(F, i, Sizeof(i));                { Read size of disk image }
  j := Longint(Sizeof(obj^)) + i             { Compute memory size }
          - Sizeof(String) - 2 * Sizeof(Word);
  GetMem(obj, j);                            { Allocate image }
  BlockRead(F, obj^.nVert, i);               { Read image from disk }
  With Obj^ Do Begin
    MemSize  := j;                           { Record FreeMem size }
    Vert := @Name[Succ(Length(Name))];       { Establish pointers to }
    Face := @Vert^[nVert];                   {   individual arrays   }
    FaceNorm := @Face^[nFace];
    VertNorm := @FaceNorm^[nFace];
  End;
  GetObj := Obj;
END;

Example of accessing a t3Dobj:

VAR p: tp3Dobj;

    p := GetObj(ObjFile, ObjOffset);

    Writeln('Object name: ', p^.Name);
    Writeln('  Vert size: ', p^.nVert);
    Writeln('  Face size: ', p^.nFace);

    Writeln('First Face z_avg: ', p^.Face^[0].z_Avg);
    Writeln('Last Face z_avg: ', p^.Face^[p^.Face^[p^.nFace-1].z_Avg);

Quote
>Anyone care to help?....hope I didn't lose anyone in the confusing
>explaination =)

Let's hope I didn't loose you with the solution. ;-)

    ...red
cc

Re:dynamic arrays inside records


I sympathize with you dilema, everbody and their mother seems to be having
trouble with dynamic arrays.

I think your best bet would be to have a look at the thread...
:Pointers/Dynamic Memory--restated

As that should give you some help.

Andy (a...@doc.ic.ac.uk)

Re:dynamic arrays inside records


Quote
In article <3355CC0B.1...@usa.net>, Valacar <valaca...@usa.net> wrote:
>Can someone help me with making a few arrays inside a record dynamic?
>The size of the arrays aren't known until the object is read in from a
>file,and the size is what I want to use to dimension those arrays.  As
>far as I know, pascal won't allow you to use one of the record fields
>(numeric of course) to dimension the arrays.  So what I did instead is
>declare the arrays from 0..MAX, where MAX is the biggest array I could
>declare before hitting the 64k limit. That works fine, but it's a total
>waste of memory when my objects are really small.

What I would in your case, would be to declare these fields as
pointers to an array (of MAX size) and at runtime GetMem with the
correct size. All that must be altered in your program is the use
of the array elements (face^[2] instead of face[2]).

Furthermore I would use an object instead of a record
and the memory allocation for the arrays would take place in the
object constructor (I would thus implement error detection as well).
The memory would be freed in the destructor using FreeMem with the
right size.

Hope this helps

Babis Athineos

--
E-mail: ba...@hol.gr
WWW : http://users.hol.gr/~babis
Snail-mail: Papadoniou 61, 11145 Athens, Greece

Re:dynamic arrays inside records


Quote
In article <3355CC0B.1...@usa.net>, Valacar <valaca...@usa.net> wrote:
>Can someone help me with making a few arrays inside a record dynamic?
>The size of the arrays aren't known until the object is read in from a
>file,and the size is what I want to use to dimension those arrays.  As
>far as I know, pascal won't allow you to use one of the record fields
>(numeric of course) to dimension the arrays.  So what I did instead is
>declare the arrays from 0..MAX, where MAX is the biggest array I could
>declare before hitting the 64k limit. That works fine, but it's a total
>waste of memory when my objects are really small.

What I would do in your case, would be to declare these fields as
pointers to an array (of MAX size) and at runtime GetMem with the
correct size. All that must be altered in your program is the use
of the array elements (face^[2] instead of face[2]).

Furthermore I would use an object instead of a record
and the memory allocation for the arrays would take place in the
object constructor (I would thus implement error detection as well).
The memory would be freed in the destructor using FreeMem with the
right size.

Hope this helps

Babis Athineos

--
E-mail: ba...@hol.gr
WWW : http://users.hol.gr/~babis
Snail-mail: Papadoniou 61, 11145 Athens, Greece

Other Threads