[fpc-pascal] A warning when Blockwriting/reading dynamic array pointers

Jürgen Hestermann juergen.hestermann at gmx.de
Fri Apr 1 18:44:55 CEST 2011


Jonas Maebe schrieb:
 >> If you Blockwrite a dynamic array pointer to file (i.e. because it 
is part of a large record) and read it back later with Blockread then 
the pointer value is invalid of course. BUT, if you now try to set it to 
nil as in
 >> DynArray := nil;
 >> then Free Pascal seems to free the memory where the pointer points to!
 > That is in fact more or less documented: 
http://www.freepascal.org/docs-html/ref/refsu15.html#x39-450003.3.1
 > "As remarked earlier, dynamic arrays are reference counted: if in one 
of the previous examples A goes out of scope and B does not, then the 
array is not yet disposed of: the reference count of A (and B) is 
decreased with 1. As soon as the reference count reaches zero the 
memory, allocated for the contents of the array, is disposed of."
 > Setting a dynamic array pointer to nil also decreases the reference 
count, since it removes a reference to the array data.

I would never expect an assignmet to nil changing anything else than 
just the value of the pointer. And for (all?) other pointers this 
expectation is valid.

 >> This creates hard to find access violations later in your program. 
This cost me days of headache because never in my life I would have 
expected that a simple assignment with nil would do more than just 
setting bytes to zero. Instead of the above assignment I had to use
 >> fillchar(DynArray,sizeof(DynArray),#0);
 >> This solved all problems.
 > It mainly creates memory leaks. If you want to keep an extra 
reference to a dynamic array's data, simply use another dynamic array.

No. Be aware that my dyn array pointer is part of a larger record 
structure which I blockwrite/-read to and from file. When I read back 
the structure the pointer is not valid. It's just the pointer at the 
time I wrote the file (could be months ago). Now I have to rebuild the 
stucture again. To do this I have to the pointer to nil so that 
following calls to SetLength have the correct assumption that no data 
has been allocated yet.




More information about the fpc-pascal mailing list