Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory corruption in a small ref-counted buffer class

Tags:

c++

I have a simple reference counted class that holds a memory buffer. It looks like this:

#include <algorithm>

template<typename T>
struct buffer
{
    // create a buffer of length n
    buffer(unsigned n) : rc(*(new unsigned(1))), data(new T[n]) { }

    buffer(const buffer<T> & rhs) : rc(++rhs.rc), data(rhs.data) { }

    buffer<T>& operator=(buffer<T> rhs)
    {
        std::swap(rc, rhs.rc);
        std::swap(data, rhs.data);
        return *this;
    }

    ~buffer()
    {
        if (--rc == 0) {
            delete [] data;
            delete (&rc);
        }
    }

private:
    mutable unsigned & rc;
    T * data;
};


int main() {
    typedef buffer<int> numbers;
    numbers n1(10);
    numbers n2(20);
    numbers n3(30);
    n1 = n2 = n3 = n2;
}

I don't see anything wrong with the code. However Visual Studio and valgrind complain about memory corruption.

I've stared at this code for way too long now. Can anyone spot the error?

like image 998
StackedCrooked Avatar asked Dec 04 '25 19:12

StackedCrooked


1 Answers

One problem is that when you swap(rc, rhs.rc); you're actually swapping the contents of the recounts, not the references.

Imagine you have this situation:

Before

When you swap(rc, rhs.rc);, the references to the refcounts will remain the same, and the counts themselves will swap. This is what you get after the two swaps:

After

The buffer pointers are corrrect, but the references to the refcounts still refer to the same unsigned objects. The value of these objects was swapped though. Notice how the buffer B has refcount 2 when seen from one of the swapped objects, and refcount 1 when seen from the one on the bottom.

You need to use pointers for the refcount, and swap the pointers, not the contents.

like image 113
R. Martinho Fernandes Avatar answered Dec 06 '25 09:12

R. Martinho Fernandes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!