Slice allocation after appending

Ali Çehreli acehreli at yahoo.com
Wed Dec 23 04:03:37 UTC 2020


On 12/22/20 2:12 PM, Rekel wrote:

 > Now I'm unsure how to check this, I tried to a bit using the online
 > editor and a bit of pointer usage which seemed to confirm my suspicion,
 > but does this mean that taking a (small) slice at the end of a
 > (possibly) very large dynamic array can lead to problematic behavior?

Considering D's "no stomp" behavior with array elements, yes, that can 
happen.

 > Again I'm not very certain I fully understood how slices are
 > implemented, but is this example, and the problem I imagine it leading
 > to, valid?

It is valid. One can always copy the small array before appending to it 
and the large array would be preserved. (Uncomment the "ADD THIS" line 
below.)

I added a nested function to your code to help visualize the states of 
the two arrays:

import std.stdio;
import std.meta;

void main() {
   int[] a = new int[10]; // Imagine this is very large
   int[] b = a[$-1..$];   // Small slice at the end

   auto info(string tag) {
     writefln!"\n(%s)"(tag);
     writeln("array      ptr            length    capacity");
     writeln("--------------------------------------------");
     static foreach (arr; AliasSeq!(a, b)) {
       writefln!"%-10s %s %8s %8s"(
         arr.stringof, arr.ptr, arr.length, arr.capacity);
     }
   }

   info("Before appending to b");
   // b = b.dup;    // <-- ADD THIS
   b ~= 2;                // b extends, possibly in place
   info("Before appending to a");
   a ~= -1;               // a no longer can, so the entire array needs
   info("At the end");
}

Try the -profile command line switch when compiling your program and it 
will show where memory allocations occur. Very helpful in exposing such 
problem spots...

Ali



More information about the Digitalmars-d-learn mailing list