Excuse me if I miss something obvious, but: void main() { auto arr = RCArray!int([0]); foo(arr, arr[0]); }
void foo(ref RCArray!int arr, ref int val) { { auto copy = arr; //arr's (and copy's) reference counts are both 2 arr = RCArray!int([]); // There is another owner, so arr // forgets about the old payload } // Last owner of the array ('copy') gets destroyed and happily // frees the payload. val = 3; // Oops. } On Mon, Mar 02, 2015 at 03:22:52PM -0800, Andrei Alexandrescu wrote: > On 3/2/15 2:57 PM, Walter Bright wrote: > > His insight was that the deletion of the payload occurred before the end > > of the lifetime of the RC object, and that this was the source of the > > problem. If the deletion of the payload occurs during the destructor > > call, rather than the postblit, then although the ref count of the > > payload goes to zero, it doesn't actually get deleted. > > > > I.e. the postblit manipulates the ref count, but does NOT do payload > > deletions. The destructor checks the ref count, if it is zero, THEN it > > does the payload deletion. > > > > Pretty dazz idea, dontcha think? And DIP25 still stands unscathed :-) > > > > Unless, of course, we missed something obvious. > > And since an RCArray may undergo several assignments during its lifetime > (thus potentially needing to free several chunks of memory), the arrays > to be destroyed will be kept in a freelist-style structure. Destructor > walks the freelist and frees the chunks. > > Andrei