Как избежать двойного освобождения или повреждения (fasttop) на операторах копирования?

У меня есть следующий класс, где я заставляю компилятор генерировать все конструкторы копирования / перемещения и операторы присваивания.

class foo {
public:
float *x;
size_t size;
foo(int m){
size = m;
x = new float[size];}

foo(const foo&) = default;
foo(foo&&) = default;
foo& operator =(const foo&) = default;
foo& operator =(foo&&) = default;

~foo(){delete [] x;}

void fill(const float& num)
{
std::fill(x,x+size,num);
}

void print()
{
for (auto i=0;i<size;++i)
cout << x[i] << endl;
cout << endl;
}
};

Тогда я звоню из main функция, как это

int main()
{
foo x(2);
x.fill(6);
x.print();foo y(2);
y = x; // causes the error

return x;
}

Теперь я знаю, что освобождаю память дважды, назначая y = x; поэтому, когда один освобожден, другой null, я прав? Я пошел дальше и реализовал свой собственный оператор назначения копирования

foo& operator=(const foo& other)
{
if (other.x!=x)
x = other.x;
return *this;
}

Тем не менее, я думаю, что здесь снова я делаю то, что делает конструктор по умолчанию в любом случае. У меня вопрос, как сделать правильный оператор копирования копии, чтобы эта проблема не возникала?

1

Решение

Вам нужно скопировать не указатель, а содержимое указателя. Хороший подход к использованию скопировать и поменять идиому поскольку ваш конструктор копирования уже должен выполнить копирование содержимого x:

friend void swap(foo& first, foo& second)
{
using std::swap;
swap(first.x, second.x);
swap(first.size, second.size);
}

foo& operator=(foo other) // note pass by value
{
swap(*this, other);
return *this;
}
1

Другие решения


По вопросам рекламы [email protected]