Path: utzoo!attcan!uunet!cs.utexas.edu!csd4.csd.uwm.edu!bionet!agate!saturn!ucscc.ucsc.edu!gorn!filbo
From: filbo@gorn.santa-cruz.ca.us (Bela Lubkin)
Newsgroups: comp.lang.pascal
Subject: Re: FreeMem, GetMem & TP50
Summary: order of deallocation has a minor transient effect on free memory
Message-ID: <6.filbo@gorn.santa-cruz.ca.us>
Date: 17 Aug 89 14:23:31 GMT
References: <1392@lafcol.UUCP>
Organization: R Pentomino
Lines: 56

In article <1392@lafcol.UUCP>, Kenwyn A. Pilgrim writes:

[paraphrase: In Turbo Pascal 5.0, if two heap blocks are allocated and then
 released in the opposite order, MemAvail acts as expected.  If they are
 released in the same order as they were allocated, the first FreeMem
 increases MemAvail by less than expected; the second by more than expected;
 but after both are released, MemAvail is as expected.]

This is an artifact of how Turbo 5's memory manager works.  I'll describe
why it happens; I leave it up to you to determine whether this has any
bearing on your problem.

Without going into a great deal of detail, the memory manager keeps track of
free memory by maintaining a list of free blocks.  When the heap is empty,
there are no free blocks in the list -- the large block at the free end of
the heap does not appear in the list and is tracked by other pointers.  The
size of the free-blocks-list floats according to how many free blocks there
are.  In the example you gave, there are no free blocks at any time in the
sequence [allocate(first); allocate(second); free(second); free(first)].  On
the other hand, in the sequence [allocate(first); allocate(second);
free(first); free(second)], a free block is created when you free(first).
Memory usage looks something like this [not to any scale]:

  initially:            -------------
  allocate(first):      *------------
  allocate(second):     **-----------
  free(first):          -*----------*
  free(second):         -------------

To keep track of the free block created by free(first), a free-block pointer
is allocated at the end of the heap.  This accounts for the missing memory
as reported by MemAvail.  free(second) allows that free block to coalesce
with the rest of the heap, so the free-block pointer goes away, its memory
becomes available again, and MemAvail once again reports the expected value.
The key point here is that MemAvail may not exactly track the amounts
allocated and freed because of this automatic allocation for the free list.

> I would like to think that the problem here is not my logic
> but the way in which TP50 handles memory allocation/deallocation :-(
From what you describe (which I will not attempt to quote), I don't >think<
the memory manager is causing your problem.  You did indeed find something
that seemed anomalous, but it's part of the normal operation of the heap.
(BTW, the heap manager does make sure that the memory it's allocating for
the free list is available...)

One thing was not clear from your posting: when the problem occurs, is the
heap very nearly full (or has it been so earlier in the program, and has
the highest allocated block not been freed)?  The free list is constrained
to the end of the heap; if the heap's nearly full, or was, and there is
still a block allocated near the end, even if others below it have been
freed, you can get an error on a deallocation because the free list is
unable to expand.

Bela Lubkin     * *   filbo@gorn.santa-cruz.ca.us   CIS: 73047,1112
     @        * *     ...ucbvax!ucscc!gorn!filbo    ^^^ REALLY slow [months?]
R Pentomino     *     Filbo @ Pyrzqxgl (408) 476-4633 & XBBS (408) 476-4945