[comp.lang.pascal] Pointers / Linked lists with files..

dragon@westfort.UUCP (The Mystic) (05/12/89)

        In one of my programs, I have need for several variables which are 
diminsioned to an array of 100, which are declared under a Record Type.. When 
I define the record and the file name in my VARS section, I'm told the 
structure is too large, then when I add the mb:array[1..50] of mbrec (Which I 
also need all 50 of the array), I'm told that there are too many variables.. 
Assumidly the only way past this is to use the pointers/linked lists with my 
record, yet I keep runnito problems doing such..  Here's what my section of 
code looks like..:

Type
mbrec=record
  t:array[1..100] of string[30];
  f:array[1..100] of string[25];
  tpc:array[1..100] of string[20];
  dte:array[1..100] of string[10];
  tme:array[1..100] of string[8];
  num:array[1..100] of integer;
  bnm:array[1..50] of string[20];
  mgs:integer;

Var
  mb:array[1..50] of mbrec;
  fm:file of mbrec;

        Any help in prodding me in the right direction? Thanks...

                                Mystic

winfave@dutrun.UUCP (Alexander Verbraeck) (05/14/89)

I suppose you are using Turbo Pascal on a personal computer
(because of your use of the string[..] construction).
The problem the compiler has with this record construction is
that it is awfully large. A quick calculation showed, that the
array structure uses more than 550 kbytes of memory. That is more
than is available for a structure. The largest possible single
structure in Turbo Pascal is 64 kbytes. This means, that one
record fits easily in memory ("only" 11 kbytes) but the whole
structure does not.

I would suggest writing the records to the file one by one. If you
need another record, write the one you had currently in memory and
read the one you need. If you want to skip to the next "array of
records", use a Seek command to position the filepointer into the
right position. This means, that you have to use a command like:

     Seek(file,StructureNumber*50+IndexNumber);

The StructureNumber denotes the number of the "total" structure you
want to access (the one of 550+ kbytes). The IndexNumber is the
index IN the original array[1..50].

I hope this helps... If you have any questions or remarks, please post
a reply or mail me directly.

---------------------------------------------------------------------
Alexander Verbraeck                            e-mail:
Delft University of Technology                 winfave@hdetud1.bitnet
Department of Information Systems              winfave@dutrun.uucp
PO Box 356, 2600 AJ  The Netherlands
---------------------------------------------------------------------

dgr0093%ritcv@cs.rit.edu (340 Ok) (05/14/89)

In article <3377@westfort.UUCP> westfort!dragon@tut.cis.ohio-state.edu writes:
>        In one of my programs, I have need for several variables which are 
>diminsioned to an array of 100, which are declared under a Record Type.. When 
>I define the record and the file name in my VARS section, I'm told the 
>structure is too large...
>
>Type
>mbrec=record
[ big record deleted]
>
>Var
>  mb:array[1..50] of mbrec;
>  fm:file of mbrec;

Well, I think I know why your compiler's complaining.. that record, under any
Pascal I can think of, would take at least 10952 bytes (that figure for IBM 
Turbo Pascal). An array of 50 of 'em would take 547,600 bytes. Ten thousand
bytes is an awful lot for any compiler to bite off as one chunk. Do you know
how long it would take to execute the loop the compiler would generate just 
for a simple assignment such as

mbrec1 := mbrec2; ?

That's a lot of stuff to be copying around. And then you have your much larger
variable mb; and you're saying you're going to be doing writes and reads of
these 534K chunks, all at once.

This is silly. You're asking the compiler to be doing work that you as the
programmer should be doing at a higher organizational level.

If that's not possible, I have 2 suggestions.

1> Look into some form of RLL encoding to shorten those strings. If you know
that the compressed length of a 100 character string will never exceed 50, an
array [1..100] of these just saved 5000 bytes.

2> If you only need one of these things at a time (which in this case I doubt),
look into using a free union variant record. That'll significantly drop the
size of each of these records.

Good luck...

Jones.

R_Tim_Coslet@cup.portal.com (05/15/89)

In Article: <3377@westfort.UUCP>
	dragon@westfort.UUCP (The Mystic) writes...
>        In one of my programs, I have need for several variables which are 
>diminsioned to an array of 100, which are declared under a Record Type.. When 
>I define the record and the file name in my VARS section, I'm told the 
>structure is too large, then when I add the mb:array[1..50] of mbrec (Which I 
>also need all 50 of the array), I'm told that there are too many variables.. 
>Assumidly the only way past this is to use the pointers/linked lists with my 
>record, yet I keep runnito problems doing such..  Here's what my section of 
>code looks like..:
>
>Type
>mbrec=record
>  t:array[1..100] of string[30];
>  f:array[1..100] of string[25];
>  tpc:array[1..100] of string[20];
>  dte:array[1..100] of string[10];
>  tme:array[1..100] of string[8];
>  num:array[1..100] of integer;
>  bnm:array[1..50] of string[20];
>  mgs:integer;
 end {mbrec record};		{ I think you forgot this line }
>
>Var
>  mb:array[1..50] of mbrec;
>  fm:file of mbrec;
>
>        Any help in prodding me in the right direction? Thanks...
You CAN'T be SERIOUS!!! :-)

Your   mbrec   takes up over 10K of memory!!!!
and the array of 50 of these will require over half a MEGA BYTE of memory!!!!

What kind of computer are you expecting to run this on????
Can't you keep some of the data in the file?

                                        R. Tim Coslet

Usenet: R_Tim_Coslet@cup.portal.com
BIX:    r.tim_coslet 

pilgrimk@lafcol.UUCP (Kenwyn A. Pilgrim) (05/15/89)

my $0.28
# 
# Type
# mbrec=record
#   t:array[1..100] of string[30];
#   f:array[1..100] of string[25];
#   tpc:array[1..100] of string[20];
#   dte:array[1..100] of string[10];
#   tme:array[1..100] of string[8];
#   num:array[1..100] of integer;
#   bnm:array[1..50] of string[20];
#   mgs:integer;
#  end;
{----- modified code -----}
  Var
    mb:array[1..50] of ^mbrec;
    fm:file of mbrec;
    i: byte; 
begin
 for i := 1 to 50 do 
 if MaxAvail >= SizeOf(mbrec) then GetMem(mbrec[i],SizeOf(mbrec))
  else writeln('Cannot allocate memory for mbrec[',i,']');
 {or write to disk somewhere}
 {to access do}
 writeln(mbrec[1]^.t[3]);
 ...
end.
 

-Kenwyn

mitch@arcturus.UUCP (Mitchell S. Gorman) (05/16/89)

In article <3377@westfort.UUCP>, dragon@westfort.UUCP (The Mystic) writes:
> [...]
> 
> Type
> mbrec=record
>   t:array[1..100] of string[30];
>   f:array[1..100] of string[25];
>   tpc:array[1..100] of string[20];
>   dte:array[1..100] of string[10];
>   tme:array[1..100] of string[8];
>   num:array[1..100] of integer;
>   bnm:array[1..50] of string[20];
>   mgs:integer;
> 
> Var
>   mb:array[1..50] of mbrec;
>   fm:file of mbrec;
>

	Turbo will not allow a single data structure to exceed 64k bytes 
(actually, it's something like 65300 or so).  

	What you may wish to do, instead of actually making mb into a
linked-list or something like that, would be to simply declare the elements
of the record to be arrays of pointers to strings, as opposed to arrays of
strings.  (The difference between storing 4 bytes of pointer instead of 31
bytes of string is obviously huge on this scale, and the changes necessary
to your code to implement this method of dealing with the problem are much
easier to effect.)

	Mitch @ Rockwell, Anaheim

Disclaimer:	Jes' a suggestion...

dragon@westfort.UUCP (The Mystic) (06/01/89)

        I did away with the mbrec=array[1..50] of mbase; and started to use a 
simple seek command to load each file as I needed it.. Still no good.. I took 
the majority of my other file (global) variables and tossed them into the 
procedures they correspond to, yet still no good.. In order for me to cut the 
rest of the garbage out, I'm either going to have to re-open a file 3-4 times 
as I go from procedure to procedure of a routir figure out how to pass 
variable (file) arrays in the procedure... I managed to do so with normal vars,
 but I can't seem to get the arrays to take, AND save thes they were passed 
with.. 

                Jason