Класс "Ломаная на плоскости"

Условие и постановка задачи: Ломаная на плоскости задаётся последовательностью пар координат, определяющих положение точек этой ломаной на координатной плоскости. Для двух ломаных определяется сумма — ломаная, состоящая последовательно из точек первой ломаной и, затем, второй ломаной. Геометрически это можно представить соединением отрезком последней точки первой ломаной и первой точки второй.Задание. Написать класс "ломаная на плоскости" и оператор "сумма ломаных";

В качестве кода я сделал следующее: ввожу 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 шт):

Автор решения: Harry

У вас нет оператора присваивания, а само присваивание есть:

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;
}
→ Ссылка