Неправильно работает сложение векторов, выдает неверный ответ и срабатывает точка останова (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 шт):
Я потратил некоторое время и нашёл решение Вашей проблемы. В методе 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 будет указывать на действительные данные.

