new operator overwriting an existing object

Posted by dvpdiner2 on Stack Overflow See other posts from Stack Overflow or by dvpdiner2
Published on 2010-12-30T23:58:28Z Indexed on 2010/12/31 0:54 UTC
Read the original article Hit count: 157

Filed under:
|

I have a custom FastStack class, implemented as a fixed size array and an index into that array.

In my copy constructor, I allocate the array and then assign each object from the copy's array into the new array. There's some refcounting in the objects on the stack, hence assignment is used rather than a simple copy.

The problem is that when allocating the array, it sometimes overwrites part of the other stack's array. As can be expected, this leads to eventual segmentation faults when that data is dereferenced.

class FastStack {
private:
    int m_size, m_ptr;
    ObjectRef* m_stack;

public:
    FastStack(int size) : m_size(size), m_ptr(-1) {
        m_stack = new ObjectRef[m_size];
    }

    FastStack(const FastStack& copy) : m_size(copy.m_size), m_ptr(copy.m_ptr) {
        long a = (long)copy.m_stack[0];

        m_stack = new ObjectRef[m_size];

        if ((long)copy.m_stack[0] != a)
            fprintf(stderr, "\nWe have a serious problem!\n\n");

        for (int i = 0; i <= m_ptr; i++)
            m_stack[i] = copy.m_stack[i];
    }

    ~FastStack() {
        delete[] m_stack;
    }
};

class ObjectRef {
private:
    DataObj* m_obj;

public:
    ObjectRef() : m_obj(0) { }

    ObjectRef(DataObj* obj) : m_obj(obj) {
        if (m_obj) m_obj->addRef();
    }

    ObjectRef(const ObjectRef& obj) : m_obj(obj.m_obj) {
        if (m_obj) m_obj->addRef();
    }

    ~ObjectRef() {
        if (m_obj) m_obj->delRef();
    }

    ObjectRef& operator=(DataObj* obj) {
        if (obj) obj->addRef();
        if (m_obj) m_obj->delRef();
        m_obj = obj;
        return *this;
    }

    ObjectRef& operator=(const ObjectRef& obj) {
        if (obj.m_obj) obj.m_obj->addRef();
        if (m_obj) m_obj->delRef();
        m_obj = obj.m_obj;
        return *this;
    }
};

I see that "We have a serious problem!" line shortly before a segfault, and stepping through it with gdb I can see that one of the ObjectRefs created by new has the same address as the other stack's array.

My first instinct is to say that new should never be allocating memory that is already in use, but that clearly seems to be the case here and I am at a complete loss as to what can be done.

Added: At the time that I see this happen, m_size = 2 and m_ptr = 0.

© Stack Overflow or respective owner

Related posts about c++

Related posts about g++