Класс "Ломаная на плоскости"
Условие и постановка задачи: Ломаная на плоскости задаётся последовательностью пар координат, определяющих положение точек этой ломаной на координатной плоскости. Для двух ломаных определяется сумма — ломаная, состоящая последовательно из точек первой ломаной и, затем, второй ломаной. Геометрически это можно представить соединением отрезком последней точки первой ломаной и первой точки второй.Задание. Написать класс "ломаная на плоскости" и оператор "сумма ломаных";
В качестве кода я сделал следующее: ввожу 2 массива произвольной длины, ну а дальще перегрузкой оператора "+" объединяю их. НО, возникает ошибка "double free detected in tcache 2".
#include <iostream>
using namespace std;
int i=0;
class Array
{
private:
int size;
unsigned int* data;
public:
// конструктор
Array(){}
Array(int asize) {
size=asize;
data=(unsigned int*)new int[size];
if(data) cout<<"Massiv inicializir\n";
else cout<<"ne hvatka pamiati\n";
}
~Array(){
delete[] data;
cout<<"Object uni4tojen\n";
}
//Далее методы
Array(const Array &ob) //Определение конструктора //копирования
{
size=ob.size;
data=(unsigned int*)new int [size];
for(int i=0;i<ob.size;i++)
data[i]=ob.data[i];
}
void print(){
for(i=0;i<size;i++){
cout<<*(data+i)<<" ";
}
cout<<endl;
}
void scan(){
cout<<"Vvedite massiv iz:"<<size<<"simvolov \n";
for(int i=0;i<size;i++){
cin>>*(data+i);
}
}
Array operator+(const Array& ob){
this->size=size;
Array tmp(size+ob.size);
for(i=0;i<size;i++)
{
tmp.data[i]=*(data+i);//this->data[i]=data[i];
}
for(i=size;i<size+ob.size;i++) tmp.data[i]=ob.data[i-size];
return tmp;
}
};
int main(){
Array first(3);
Array second(2);
first.scan();
second.scan();
Array third(5);
third=first+second;
third.print();
return 0;
}
Прошу объяснить Почему возникла эта ошибка(скорее всего всё из-за выделения доп.памяти) и способ ее исправления. Спасибо.
Кстати, я задавал ранее вопрос про Ломаную,условие такое же, но код не подходящий, поэтому я решил задать отдельный вопрос про эту задачу,но уже с нужным мне кодом.
Ответы (1 шт):
У вас нет оператора присваивания, а само присваивание есть:
third=first+second;
Соответственно, он генерируется компилятором, при этом выполняется простое почленное присваивание (т.е. просто присваивание указателей, а не копирование содержимого памяти), что в результате вызывает утечку памяти (память объекта third не удаляется) + приводит к освобождению одной и той же памяти дважды (временного объекта, создаваемого при суммировании, и объекта third).
Помните о правиле большой тройки :) — если уж работаете с памятью — деструктор, копирующий конструктор и оператор присваивания обязательны...
Рекомендую идиому присваивания через копирование: пишется функция swap для обмена членов двух объектов, потом создается временный объект, обмен с ним — и все готово. В вашем варианте примерно так:
void swap(Array& a) {
std::swap(size,a.size);
std::swap(data,a.data);
}
Array& operator=(const Array& a)
{
if (this != &a) { // Необязательно!!
Array tmp(a);
swap(tmp);
}
return *this;
}