RCArray is unsafe

Ivan Timokhin via Digitalmars-d digitalmars-d at puremagic.com
Wed Mar 4 00:55:20 PST 2015


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


More information about the Digitalmars-d mailing list