Is it possible to append to a local buffer without reallocating?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Thu Jan 11 12:38:44 UTC 2018


On Thursday, January 11, 2018 11:21:08 tipdbmp via Digitalmars-d-learn 
wrote:
> string push_stuff(char[] buf, int x) {
>      if (x == 1) {
>          buf ~= 'A';
>          buf ~= 'B';
>          buf ~= 'C';
>          return cast(string) buf[0 .. 3];
>      }
>      else {
>          buf ~= 'A';
>          buf ~= 'B';
>          return cast(string) buf[0 .. 2];
>      }
> }
>
> void foo() {
>      {
>          char[2] buf;
>          string result = push_stuff(buf, 1);
>          assert(buf.ptr != result.ptr);
>      }
>
>      {
>          char[2] buf;
>          string result = push_stuff(buf, 0);
>          assert(buf.ptr == result.ptr); // <-- this assert fails
>      }
> }

A dynamic array can only expand in place without reallocating if its memory
was allocated by the GC for a dynamic array, and it's the farthest slice
into that block of memory (so that appending to it wouldn't overlap with
another array). A dynamic array which is a slice of a static array is not
allocated by the GC to be a dynamic array; it was allocated on the stack to
be a stack array. So, appending to it even once would cause it to be
reallocated.

But if you want to know whether reallocation is going to occur, then check
the array's capacity. If the capacity is the length of the dynamic array or
less, then appending will cause it to reallocate. For a dynamic array backed
by a static array or malloc-ed memory or anything other than memory
allocated by the GC to be a dynamic array, the capacity will be 0.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list