.dup on an array of BitArray not duplicating

Chris Cain clcain at uncg.edu
Tue May 15 13:16:27 PDT 2012


On Tuesday, 15 May 2012 at 19:23:31 UTC, ixid wrote:
> Not sure if this is a bug or just rather counter-intuitive:
>
> BitArray test;
> test.length = 7;
> BitArray test2 = test.dup;
> test2[0] = 1;
>
> This is fine, test is not modified.
>
> BitArray test[7];
> foreach(ref i;test)
>     i.length = 7;
> BitArray[7] test2 = test.dup;
> test2[0] = 1;
>
> test has been modified. Why doesn't dup work here?

dup doesn't make a deep copy. That is to say, you have a dup'd 
array of items that have not had dup called on them.

BitArray (? Are you using D1?) apparently uses pointer to its 
payload. In the first case, you're using BitArray's dup property 
which knows to create a new payload with the same values as the 
original.

The second case, you call dup on the static array of BitArrays 
which makes an exact bit-for-bit copy of the BitArray structs in 
the array. So, you're getting a new "BitArray" struct which has 
the exact same information (in this case, including a pointer) as 
the old BitArray.

So, when you call opAssign (using the test2[0] = 1;), it modifies 
the payload of the first BitArray, which transitively means that 
the first BitArray in test also sees the change (because it is 
using a pointer to the same payload).


Also, just as an aside, your first and second examples don't mean 
exactly the same thing when you do "test2[0] = 1;" In the first 
one, you're (probably) using BitArray's opIndexAssign and the 
second one, you're just using BitArray's opAssign.

An equivalent call for the second example would be:
test2[0][0] = 1;

Which would still have the same problem as you'd still be 
modifying the payload being pointed at. But it's just something 
to mention.


More information about the Digitalmars-d-learn mailing list