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