[fpc-pascal] ReAllocMem problem (?)

Micha Nelissen micha at neli.hopto.org
Sat Mar 12 18:31:03 CET 2005


> ---------------------------- Original Message ----------------------------
> Subject: Re: [fpc-pascal] ReAllocMem problem (?)
> From:    "Marcel Martin" <mm10 at ellipsa.net>
> Date:    Wed, January 19, 2005 0:57
> To:      "FPC-Pascal users discussions" <fpc-pascal at lists.freepascal.org>
> --------------------------------------------------------------------------
> 
> Marcel Martin a écrit :
> >
> > Hello,
> >
> > The following function SysReAllocMem comes from the file
> > /rtl/inc/heap.inc (FPC 1.9.7 / Win32)
> >
> > function SysReAllocMem(var p: pointer; size: ptrint):pointer;
> > [...]
> >    { Resize block }
> >    if not SysTryResizeMem(p,size) then
> >    begin
> >      minsize := MemoryManager.MemSize(p);
> >      if size < minsize then
> >        minsize := size;
> >      p2 := MemoryManager.AllocMem(size);
> >      if p2<>nil then
> >        Move(p^,p2^,minsize);
> >      MemoryManager.FreeMem(p);
> >      p := p2;
> >    end;
> > [...]
> >
> > Maybe you have good reasons to write it like you did but is
> > the instruction "MemoryManager.FreeMem(p);" intentionally
> > always executed?
> > I thought that, in case it cannot increase the size of the
> > memory allocated to p^, the memory manager would set p to nil
> > but not that it would free it.
> >
> > Suppose OneClass has a field FP which points to an array of
> > pointers. In case of problem when attempting to increase the
> > size of FP^, FP is freed and OneClass can no more destroy the
> > pointed objects it created.
> >
> > Up to now, I believed the code was something like
> >
> >   if p2<>nil then
> >   begin
> >     Move(p^,p2^,minsize);
> >     MemoryManager.FreeMem(p);
> >   end;
> >   p := p2; <- p might be set to nil but it is not freed
> >
> > and, in OneClass, one could do
> >
> >   Q := FP;
> >   ReAllocMem(FP, NewSize (greater than current size));
> >   if FP = nil then
> >   begin
> >     FP := Q;
> >     Signal the 'Out of Memory' problem
> >   end;
> >
> > Was your programming intentional? And if so, why?
> > Thanks.
> 
> Considering the numerous answers I received, I am going to ask the
> questions otherwise: Is it a bug or not? Should I wait for a fixed version
> or should I manage to use it as it is because it will stay as it is?  :-)
> Thanks.

The problem with your approach is: how do you know whether the memory was extended, or left alone because there was no memory available to extend it ? In general, shortage of memory produces a runtime error, but this is configurable by a global var.

> There is an other thing I didn't notice yesterday when I sent my
> post. SysReAllocMem makes use of MemoryManager.AllocMem instead of 
> MemoryManager.GetMem, i.e., SysReAllocMem fills up with 0s the
> new allocated memory (whereas the ReAllocMem doc says "only the
> used memory is initialized, extra memory will not be zeroed out").

Not zeroing it would trigger a bug in the compiler, so I left it in. (Can not remember precisely, but the context was an array of pointers that is realloc'ed, needing the new entries to be zero/nil).

Micha




More information about the fpc-pascal mailing list