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();
}
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 delete
s the old values
, but then just blindly sets values
to point to something that was never new
ed (the new_values
that get passed into here are not new
ed anywhere).
Hence, later, this object's destructor attempts to delete
what's now in values
, but it was never new
ed (it just points to some static array) and you get the runtime error.