LastReadWriteStrFDR is used to cache an FDR to avoid allocating and releasing one for each use of ReadStr, Val etc.
Unfortunately, the memory is leaked since it is never freed and there is no way to cause it to be freed. This causes my leak detection routines to fire on termination of my program.
I've added to files.pas:
procedure DisposeReadWriteStr; attribute (name = '_p_DisposeReadWriteStr');
procedure DisposeReadWriteStr; begin if LastReadWriteStrFDR <> nil then begin InternalDispose (LastReadWriteStrFDR); LastReadWriteStrFDR := nil end end;
which cannot do any damage since LastReadWriteStrFDR is just a cache and calling it before checking for leaks solves my problem, but:
* the name DisposeReadWriteStr is pretty dubious * I'm not convinced this is the best way to do it * perhaps exposing LastReadWriteStrFDR is a better solution (then at least I could detect the leak matches that and hide it)
a to end do block could clean up the LastReadWriteStrFDR FDR, but that would not happen until after my code had all completed and so I'd still register the leak.
This also highlights a risk involved in using the GetMemPtr/FreeMemPtr/ReAllocMemPtr variables to define replacement memory allocators. Since some allocations (eg StdErr's FDR) are allocated before my code can be executed, they are allocated with the default memory allocator and not with mine. It is therefore imperitive that they not be freed until after I have replaced the FreeMemPtr with the original (CFreeMem). So the RTS needs to be careful that anything that is allocated within _p_initialize is not freed until _p_finalize, and also nothing allocated after _p_initialize completes and user code starts can be freed safely in _p_finalize.
I'm open to any suggestions on any of this. Peter.
Peter N Lewis wrote:
LastReadWriteStrFDR is used to cache an FDR to avoid allocating and releasing one for each use of ReadStr, Val etc.
Unfortunately, the memory is leaked since it is never freed and there is no way to cause it to be freed. This causes my leak detection routines to fire on termination of my program.
<snip>
a to end do block could clean up the LastReadWriteStrFDR FDR, but that would not happen until after my code had all completed and so I'd still register the leak.
This also highlights a risk involved in using the GetMemPtr/FreeMemPtr/ReAllocMemPtr variables to define replacement memory allocators. Since some allocations (eg StdErr's FDR) are allocated before my code can be executed, they are allocated with the default memory allocator and not with mine. It is therefore imperitive that they not be freed until after I have replaced the FreeMemPtr with the original (CFreeMem). So the RTS needs to be careful that anything that is allocated within _p_initialize is not freed until _p_finalize, and also nothing allocated after _p_initialize completes and user code starts can be freed safely in _p_finalize.
Buffers for StdErr and friends used to be (initialized) static variables. They were changed to dynamic allocation to save disc space. However, on most systems uninitialized variables are not stored in binaries or libraries, so making buffers just into uninitialized variables should be almost as good (in disc space usage) as dynamic allocation. Having them static should avoid most allocation/deallocation problems. OTOH that would make runtime less uniform (since it is an error to free static buffer).
Concerning your problem: yes, buffers allocated by _p_initialize should be freed by _p_finalize, so any Pascal leak detector will see them as allocated. But it should see them as allocated also at start of the program, so maybe it is not a problem.