[fpc-pascal] Question about Deleting elements in Dynamic Array

David Emerson dle3ab at angelbase.com
Wed Apr 28 10:47:34 CEST 2010


Vincent Snijders wrote:
> Bihar Anwar schreef:
> > I've tried to use Move() instead of Copy(). Any objection with the following
> > code?
> 
> Yes, at first glance without much thinking, I don't think it is safe. Did you
> think through the consequences of copying reference counted types (ansistring
> in this case presumably)?
>
> > System.Move(a[3], a[0], 2 * SizeOf(string) );
> > SetLength(a, 2);
> 

The above works great for me for non-reference counted types; I use it 
extensively (most common usage is adding an element into the middle of a sorted 
list. Incidentally, if doing this, it's also good to manage the length 
intelligently, so it does not need to reserve memory each time it adds one 
element. anyway......)

For ref-counted types, a couple extra operations are needed in order to keep all 
the reference counts correct.

Before the move: for all the data that is going to be destroyed, set it to nil 
(setting an ansistring/dynarray to nil does the same thing as setlength to 0 -- 
namely, it adjusts the reference count, and frees it if needed)

for i := 0 to 2 do a[i] := nil;
System.Move(a[3], a[0], 2 * SizeOf(ansistring) );

After the move: duplicated data will now have an inaccurate ref-count (e.g. ref 
count = 1 instead of the actual 2), so we have to use fillbyte to zero out the 
old refs.

fillbyte (a[2], 3*sizeof(ansistring), 0);
SetLength(a, 2);

Note: you're playing with fire here, be really really careful. If you make the 
tiniest error, your data will become corrupt and your program will crash, and 
there will be no warnings or anything to help you fix the horrific mess you've 
created. And I haven't tested the code above... I've written the same stuff 
many times, but I always scrutinize it super-carefully and test the living crud 
out of it.

Consider whether your potential performance increase will be worth hours of 
debugging -- I have spent those hours!! -- and potential crashes from 
unauthorized memory accesses.

Cheers,
David




More information about the fpc-pascal mailing list