Array length & allocation question
Sean Kelly
sean at f4.ca
Tue Jun 13 09:05:57 PDT 2006
Oskar Linde wrote:
> Derek Parnell skrev:
>> On Tue, 13 Jun 2006 01:05:04 +0200, Oskar Linde wrote:
>>
>>>> Setting the length to zero is a convenient way to reserved RAM for
>>>> an array.
>>> t arr.length = 100_000_000; arr = arr[0..0]; is almost as convenient.
>>
>> Unfortunately this only appears to reserve the RAM, because the next
>> change
>> in length will cause a new allocation to be made. See the example program
>> below ...
>>
>>>> Also consider this ...
>>>>
>>>> foo("");
>>>>
>>>> Now how can 'foo' be written to detect a coder's error of passing it
>>>> an uninitialized array.
>>>>
>>>> char[] x;
>>>> foo(x);
>>>>
>>> Like this:
>>>
>>> void foo(char[] arr) {
>>> if (!arr)
>>> writefln("Uninitialized array passed");
>>> else if (arr.length == 0)
>>> writefln("Zero length array received");
>>> }
>>
>> Yes, I can see that D can now distinguish between the two. This didn't
>> used
>> to be the case, IIRC. However there is still a 'bug' with this as the
>> program here demonstrates...
>>
>>
>> import std.stdio;
>> void main()
>> {
>> char[] arr;
>>
>> foo(arr);
>> foo("");
>> foo("".dup);
>>
>> writefln("%s %s", arr.length, arr.ptr);
>> arr.length = 100;
>> writefln("%s %s", arr.length, arr.ptr);
>> arr = arr[0..0];
>> writefln("%s %s", arr.length, arr.ptr);
>> arr.length = 50;
>> writefln("%s %s", arr.length, arr.ptr);
>> arr.length = 500;
>> writefln("%s %s", arr.length, arr.ptr);
>>
>> }
>>
>> void foo(char[] t)
>> {
>> writefln("foo: %s %s", t.length, t.ptr);
>> }
>>
>> The results are ...
>> foo: 0 0000
>> foo: 0 413080
>> foo: 0 0000 *** A 'dup'ed empty string is now a null string.
>> 0 0000
>> 100 8A2F00
>> 0 8A2F00 *** RAM appears to be reserved.
>> 50 8A1F80 *** But it is not as a new allocation just occurred.
>> 500 8A3E00 *** This allocation is expected.
>
> You are right, changing length forces a reallocation. Interestingly, the
> following works:
>
> arr.length = 100;
> arr = arr[0..0];
> writefln("%s %s",arr.length,arr.ptr);
> for (int i = 0; i < 50; i++)
> arr ~= i;
> writefln("%s %s",arr.length,arr.ptr);
>
> prints (for me):
>
> 0 b7ee9e00
> 50 b7ee9e00
>
> What is even more interesting is that the above "buggy" behavior seems
> intentional.
Hrm, there were some changes to gc.d a while back, but it was more than
10 versions ago as that's as far back as I have installed at the moment.
Perhaps Walter could comment on the change? I suspect it was probably
a bug fix.
Sean
More information about the Digitalmars-d-learn
mailing list