guitarist2404
@guitarist2404

Как исправить ошибку в программе на С++, чтобы не вызывалось необработанное исключение или кнопка останова?

Пишу лабораторную по программированию, возникает ошибка, связанная, как я понял, с утерей памяти (программа - написание функций для сложения, вычитания, умножения, деления и скалярного произведения для векторов в n-мерном пространстве. (Пишу в VS на C++(ООП))

Сам код

//h файл
#pragma once
#include <iostream>


class Vector {
private:
    double* coord;
    int size;
public:
    Vector(const Vector& vec);
    Vector(int n);
    Vector operator+(const Vector& vec);
    Vector operator-(const Vector& vec);
    Vector operator*(const Vector& other);
    Vector operator/(const Vector& other);
    double scalar(Vector x, Vector y);
    double length() const;
    void set(int pos, double value);
    friend std::ostream& operator<<(std::ostream& os, const Vector& vec);
};

//cpp файл

#include "Vector.h"
#include <iostream>

Vector::Vector(const Vector& vec) {
    
    coord = vec.coord;
    size = vec.size;
}


Vector::Vector(int n) {
    coord = new double[size];
    for (int i = 0; i < size; i++) {
        coord[i] = 0;
    }
    size = n;
}

void Vector::set(int pos, double value)
{
   coord[pos] = value; 
  
}

Vector Vector::operator+(const Vector& vec) {
    for (int i = 0; i < size; i++) {
        coord[i] = coord[i] + vec.coord[i];
    }
    return *this;
}
Vector Vector::operator-(const Vector& vec) {
    for (int i = 0; i < size; i++) {
        coord[i] = coord[i] - vec.coord[i];
    }
    return *this;
}
Vector Vector::operator*(const Vector& scalar) {
    for (int i = 0; i < size; i++) {
        coord[i] = coord[i] * scalar.coord[i];
    }
    return *this;
}
Vector Vector::operator/(const Vector& scalar) {
    for (int i = 0; i < size; i++) {
        coord[i] = coord[i] / scalar.coord[i];
    }
    return *this;
}

double Vector::length() const {
    double result = 0;
    for (int i = 0; i < size; i++) {
       result += pow(coord[i], 2);
   }
   return sqrt(result);
}
//
double Vector::scalar(Vector x, Vector y) {
    double res = 0;
    for (int i = 0; i < size; i++) {
        res += x.coord[i] * y.coord[i];
    }
    return res;
}

std::ostream& operator<<(std::ostream& os, const Vector& vec) {
    os << "(";
    for (int i = 0; i < vec.size; i++) {
        os << vec.coord[i];
        if (i != vec.size) {
            os << ", ";
        }
    }
    os << ")";
    return os;
}

//main.cpp файл

#include <iostream>
#include "Vector.h"

using namespace std;


int main() {



    Vector vector1(3);
    Vector vector2(3);

    vector1.set(0, 1);
    vector1.set(1, 2);
    vector1.set(2, 3);
    vector2.set(0, 4);
    vector2.set(1, 5);
    vector2.set(2, 6);

    cout << "Vector1" << vector1 << endl;
    cout << "Vector2" << vector2 << endl;
    Vector vector3 = vector1 + vector2;
    cout << "sum" << vector3 << std::endl;

    Vector vector4 = vector1 - vector2;
    cout << "difference" << vector4 << endl;

    Vector vector5 = vector1 * vector2;
    cout << "multyplation" << vector5 << endl;

    Vector vector6 = vector1 / vector2;
    cout << "division" << vector6 << endl;


    double length1 = vector1.length();
    double length2 = vector2.length();
    cout << "Length of vector1: " << length1 << endl;
    cout << "Length of vector2: " << length2 << endl;

    double scalar = vector1.scalar(vector1, vector2);

    
    cout << "Dot product of vectors = " << scalar << endl;
}


Ошибка выскакивает в функции:

std::ostream& operator<<(std::ostream& os, const Vector& vec) {
    os << "(";
    for (int i = 0; i < vec.size; i++) {
        os << vec.coord[i];
        if (i != vec.size) {  //компилятор ругается на эту строчку
            os << ", ";
        }
    }
    os << ")";
    return os;
}


Подскажите, пожалуйста, в чём ошибка, и связана ли она с конструкторами класса, или дело в самой функции?
  • Вопрос задан
  • 97 просмотров
Решения вопроса 1
@dima20155
you don't choose c++. It chooses you
Вообще вы написали лишь часть вопроса. А как ругается? Если ругается компилятор, то это никак не необработанное исключение, которые вылетает в рантайме. Напишите как ругается компилятор, какое у вас исключение.
1. Ошибка компилятора.
Возможно, компилятор ругается (особенно, если включен флаг -Werror) на бессмысленность данного if потому что оно всегда ложно.

Я бы заменил код вывода в поток чем-то таким. Текста чуть больше, зато никаких if внутри цикла:
std::ostream& operator<<(std::ostream& os, const Vector& vec) {
    os << "(";
    if (vec.size) {
        for (int i = 0; i < vec.size - 1; i++) {
            os << vec.coord[i];
        }
        os << vec.coord[vec.size - 1]; // последний элемент
    } else {
       os << "Unfortunately I'm an empty vector";
    }
    os << ")";
    return os;
}

2. На счет исключений:
Исключения нужно ловить и обрабатывать или не допускать (зависит от архитектуры). Необработанное исключение говорит о том, что ваша программа работает не отрабатывает корректно во всех возможных ситуациях, поскольку зачастую никто не хочет, чтобы программа завершалась ошибкой внезапно, в худшем случае вы должны хотя бы оповестить пользователя о том что произошло. Самый простой способ получить исключение - поделить на 0 число с фиксированной точностью.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Уровень доступа private не разрешает использовать член класса size во вне.
Ответ написан
@res2001
Developer, ex-admin
1. у вас в конструкторе выделяется динамическая память. Но деструктора у вас нет. Память не освобождается, после удаления объекта - утечка.
2. Еще про конструктор. Внимательно посмотрите на строчку: coord = new double[size];.
Чему равно значение переменной size в ней? Какого размера выделится буфер?
3. Конструктор копирования реализован не правильно. Если вы создадите объект с его использованием, то он будет использовать тот же блок динамической памяти, что и исходный объект. Ни к чему хорошему это не приведет, вряд ли вы рассчитывали на такое поведение.

На счет ошибки компилятора - хорошо бы увидеть текст ошибки. Условие в operator<< действительно всегда ложно. Надо сравнивать с vec.size - 1
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы