c++unique-ptrdelete-operatorrvalue-referencetemplate-classes

Rvalue and Move Semantics with Unique Pointer: error for object 0x7ffee5c7b670: pointer being freed was not allocated


I am trying to understand how unique pointers and move semantics. Now, I have created a dummy example below to show what the issue is. My question is, why does this code throw a pointer being freed was not allocated error?:

#include <iostream>
#include <memory>

using namespace std;

template <class T>
class Object
{
public:
    T *values = nullptr;
    int size;
    Object(int size) : size(size)
    {
        values = new T[size];
    }

    ~Object()
    {
        delete[] this->values;
    }

    void myFunc(T *&&new_values)
    {
        cout << "myFunc called!" << endl;
        delete[] this->values;
        values = new_values;
    }

    void print()
    {
        for (int i = 0; i < size; i++)
            cout << this->values[i] << " ";
        cout << endl;
    }
};

int main()
{
    auto my_object = new Object<int>(4);
    std::unique_ptr<Object<int>> my_other_object(new Object<int>(4));

    int values[4] = {1, 2, 3, 4};
    int my_other_values[4] = {10, 20, 30, 40};

    /* This works all fine! */
    my_object->myFunc(std::move(values));
    my_object->print();

    /* This next bit throws pointer being freed was not allocated */
    my_other_object->myFunc(std::move(my_other_values));
    my_other_object->print();
}

Solution

  • This has nothing to do with std::unique_ptr. The reason you get the "pointer being freed was not allocated" error is because the shown code is trying to delete something that was not newed.

        delete[] this->values;
        values = new_values;
    

    This properly deletes the old values, but then just blindly sets values to point to something that was never newed (the new_values that get passed into here are not newed anywhere).

    Hence, later, this object's destructor attempts to delete what's now in values, but it was never newed (it just points to some static array) and you get the runtime error.