Неправильно работает сложение векторов, выдает неверный ответ и срабатывает точка останова (delete_scalar)

Неправильно работает сложение векторов, выдает неверный ответ и срабатывает точка останова (delete_scalar).

Vector.h:

class Vector
{
    double* a;
    int size;
    int count;

public:
    Vector();      
    Vector(int s); 
    ~Vector();       
    double& operator[](int index); 
    friend Vector operator+(Vector v1, Vector v2);
    void setarray(); 
    void getarray();    
};

Vector.cpp:

Vector::Vector()
{
    size = 10;
    a = new double[size];
    for (size_t i = 0; i != size; i++) {
        a[i] = 0.0;
    }
}

Vector::Vector(int s)
{
    if (s > 0) {
        size = s;
        a = new double[size];
        for (size_t i = 0; i != size; i++) {
            a[i] = 0.0;
        }
    }
    else cout << "Size can't be negativ";
}

Vector::~Vector()
{
    delete[]a;
}

double& Vector::operator[](int index)
{
    if (index <= size) {
        return a[index];
    }
    else {
        cout << "Элемента по данному индексу нет" << endl;
    }
}


void Vector::setarray()
{
    for (size_t i = 0; i != size; i++) {
        cin >> a[i];
    }
}

void Vector::getarray()
{
    for (size_t i = 0; i != size; i++) {
        cout << a[i] << " ";
    }
}

Vector operator+(Vector v1, Vector v2)
{
    Vector v3(v1.size);
    for (size_t i = 0; i != v1.size; i++) {
        v3[i] = v1[i] + v2[i];
    }
    return v3;
}

Main.cpp:

int main()
{
    Vector a(2);
    Vector b(2);
    a.setarray();
    b.setarray();
    (a + b).getarray();
   
}

Вызвыно исключение: введите сюда описание изображения

Почему то размер v1 = 16447572, а не 6. это как?

введите сюда описание изображения


Ответы (1 шт):

Автор решения: V-Mor

Я потратил некоторое время и нашёл решение Вашей проблемы. В методе operator+ вызывается return v3;, что, по сути, вызывает копирование только что созданного вектора из метода operator+ в вызывающую функцию. Т.к. вызывается именно копирование, срабатывает стандартный конструктор копирования, т.е. все поля класса просто-напросто дублируются в новом объекте, в том числе и указатель a. А т.к. после выхода из метода (а, следовательно, и из области видимости) объект v3 разрушается, то, как Вы указали в деструкторе, память, выделенная под массив a, освобождается. Итого получаем, что после возврата значения из метода operator+ в вызывающей функции у Вас остаётся объект Vector, у которого атрибут a является невалидным указателем на очищенную память. Отсюда и ошибки.

Чтобы избежать данной проблемы, Вам следует определить конструктор копирования, который бы корректно осуществлял перенос значений динамической памяти в новый объект. Я сделал это так:

Vector::Vector(const Vector& other): size(other.size), count(other.count)
{
    a = new double[other.size];
    for (size_t i = 0; i < other.size; ++i)
    {
        a[i] = other.a[i];
    }
}

Здесь я в новом объекте выделяю для a новую память и копирую в неё значения из копируемого объекта. Таким образом, в вызывающей функции останется объект Vector, у которого поле a будет указывать на действительные данные.

→ Ссылка