[fpc-pascal] Question about Deleting elements in Dynamic Array
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, a, 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
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, a, 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
fillbyte (a, 3*sizeof(ansistring), 0);
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.
More information about the fpc-pascal