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

Jonas Maebe jonas.maebe at elis.ugent.be
Fri Apr 1 18:49:41 CEST 2011


On 01 Apr 2011, at 18:44, J├╝rgen Hestermann wrote:

> 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.

That expectation is not valid for any reference counted type (be it a dynamic array, ansistring, unicodestring, COM-style interfaces). That's the whole point of reference counted types: they keep track of how many references still exist to the data, and once that reaches zero the data is freed.

> 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.

The correct way to do so is to call initialize() on the field.


Jonas


More information about the fpc-pascal mailing list