Memory allocation in D (noob question)

Steven Schveighoffer schveiguy at yahoo.com
Tue Dec 4 08:19:05 PST 2007


"Oskar Linde" wrote
> Try this:
>
>         char[] ab = "ab".dup;
>         char[] a = ab[0..1];
>         a ~= "c";
>         writefln("ab = ",ab);

Outputs "ac"

So this appears to be a bug then.  Because from the spec:

"Concatenation always creates a copy of its operands, even if one of the 
operands is a 0 length array"

and then for the append operator example:

"a ~= b;		// a becomes the concatenation of a and b"

Changing the line to a = a ~ "c" changes the output of the program to "ab".

Another reason why this is seems to be a bug and NOT a feature:

        string ab = "ab".idup;
        string a = ab[0..1];
        a ~= "c";
        writefln("ab = ",ab); // also outputs "ac"

This changes an invariant string without compiler complaint!

Note that Tango has this problem too.

>
>>> So appending to the [$..$] array would (without padding) mean that you 
>>> corrupt the following array.
>>
>> I think this is incorrect for the reasons I stated above.  An allocated 
>> block should never be re-assigned to another array.
>
> See my example above. The allocated block is deduced from the slice .ptr. 
> If the pointer points at the start of another array, DMD would have no way 
> of knowing it isn't a slice of that other array.

I think your example exposes a bug, and does not agree with what the spec 
says.

There seems to be a silent agreement among everyone that D should behave 
that way, but I can't find anything in the spec that states it should.  Is 
this something that is planned to be fixed or at least described correctly 
in the spec?

If someone desires this behavior, I would say that it's possible to keep a 
reference to the entire array and use the copy operator.  i.e.:

ab[1..$] = "c";

perhaps there could be another way to extend the slice if more buffer space 
exists?  With the caveat that you know that if you have other references to 
that data, they could be changed too?  I can see the usefulness of using an 
array as a buffer which keeps its allocated space as it shrinks, but this is 
not worth having x ~= y not mean the same thing as x = x ~ y.  The current 
meaning is too error prone in my opinion.

-Steve 





More information about the Digitalmars-d mailing list