0

Consider for example a template container class that holds a buffer that is allocated on the heap:

T *_buffer = new T[SIZE]

Just a simple pointer to c array of type T.

This class is templated. However I am having issues with performing a deep copy of an object into my buffer.

In my unit test, i set up a test class:

class test
{
public:
    int* _ptrInt;
    test() {_ptrInt = nullptr;}
    test(const int i)
    {
        _ptrInt = new int;
        *_ptrInt = i;
    }
    test(const test& other)
    {
        _ptrInt = new int;
        *_ptrInt = *other._ptrInt;
    }
    ~test()
    {
        delete _ptrInt;
    }
};

on my container I call set, passing a temporary as the data:

container.set(0, test(5));

// destructor called on copy immediately after statement, invalidating deep copy in buffer
void set (const int& index, const T& data)  
{ 
    int i = realign(index);
    T copy = data;
    _buffer[i==SIZE?i-1:i] = copy;   // ternary statement and index work
}

however, _buffer takes copy as a reference, the moment copy goes out of scope, it deletes the same pointer that is held in the _buffer. I am trying to force the _buffer to assign by value. But I have had no luck.

  • memcpy still copies the pointers to point to the same address
  • test copy constructor is correctly called
  • move semantics would require class to have move constructor
  • std::vector somehow implements this to copy correctly, whether its T/T*, heap/stack, with/without move constructor, so I know it must be possible

Is there a way I can assign by value to the _buffer on the heap?

Igneous01
  • 719
  • 1
  • 10
  • 24

1 Answers1

3

You are "assigning by value." However, your test class doesn't implement the assignment operator operator=, so the assignment invokes the compiler-generated default assignment operator which simply copies member-by-member. Hence the problems with shallow assignment.

Also, your copy constructor will explode if other._ptrInt is nullptr.

Casey
  • 41,449
  • 7
  • 95
  • 125
  • you are right. the default assignment operator was shallow copying which was giving incorrect copy to container. However, this same class above worked in std::vector, but im sure how they implemented deep copying there. – Igneous01 Jul 23 '13 at 00:08
  • @David `std::vector` does some tricky stuff to avoid default-initializing its buffer, and actually copy-initializes elements inplace from the values you insert. The test could have been successful if the `vector` never had to reallocate its buffer and copy live elements. – Casey Jul 23 '13 at 00:15