[comp.lang.pascal] Dynamic array written to file

ZCCBJSB%EB0UB011.BITNET@cunyvm.cuny.edu (Josep Sau B.) (04/22/91)

William C. Thompson <wct@po.cwru.edu> said:

> Say I want to save a dynamically sized structure.  People
>...
> The problem is that I need to save this to disk so that it can
> be recalled as quickly as possible.  Instead of a text file
> with numbers written on it (way too slow and too big), I need
> a FILE of something.  But a FILE of what and how large will the
> file be?
>...
>FILE of bufferptr^
>   is this even legal?  if it is, this looks like the
>   proper solution

The construction Identifier  may only be used to dereference
a pointer varaible to obtain the contents of the variable
pointed by that pointer. It is not allowed in a type declaration.

>...more stuff deleted!

To read/write to a file the elements of a dynamically allocated
array you need to manage individually each of the allocated
elements in the array:


CONST
  MaxElement = 10000; (* Max.Index you are likely to use *)

TYPE
  ElementPtrArr : ARRAY 1..MaxElement! OF Element;
  ElementFile   : FILE OF Element;

VAR
  TheArray : ElementPtrArray;
  TheFile  : ElementFile;

PROCEDURE GetElement (i :WORD; VAR Value :Element);
  BEGIN
    IF TheArrayi! = NIL
      THEN Value := NulElement
      ELSE Value := TheArrayi!;
  END;

PROCEDURE WriteElementArray;
  VAR i :WORD;
  VAR AnElement : Element;
  BEGIN
    Assign (TheFile,...);
    Rewrite(TheFile);
    FOR i := 1 TO MaxElement DO BEGIN
      GetElement(i, AnElement);
      IF AnElement <> NulElement THEN Write(TheFile,AnElement);
    END;
    Close(TheFile);
  END;

Also, it would be convenient to have the corresponding sub-programs
to manage those elements the easy way:

PROCEDURE NewElement(i :WORD);
  BEGIN
    New(TheArrayi!);
  END;

PROCEDURE DisposeElement(i :WORD);
  BEGIN
    Dispose(TheArrayi!);
    TheArrayi! := NIL;  (* Get sure undefined ptr = NIL *)
  END;

PROCEDURE SetElement(i :WORD; value :Element);
  BEGIN
    TheArrayi! := Value;
  END;

PROCEDURE ReadElementArray;
...

If the generic element is any kind of STRING or some other type
with dynamically varying size (run-time defined size, not declared
size) it would be more convenient to use GetMem and FreeMem, but
for a fixed size element it's better to rely on strict type checking
performed by New and Release...

--Josep Sau B.