E
E
Evgeniy V.2020-12-20 10:21:48
C++ / C#
Evgeniy V., 2020-12-20 10:21:48

Why does it throw an "access violation" error and divide by zero, but there is no zero?

I can't understand why it throws the error "access violation when reading at the address", and in different places
AND division by zero when searching for a determinant?

#include <iostream>
#include <string>

using namespace std;

//Создаем класс для матрицы
template <typename T>
class Matrix {
private:
  //Поля
  int size;
  T** matrix;

  //Метод для выделения памяти
  void set() {
    //Выделить память для матрицы
    //Выделить пам'ять для массива указателей
    this->matrix = (T**) new T * [size]; //Количество строк, количество указателей

    //Выделить память для каждого указателя
    for (int i = 0; i < size; i++) {
      this->matrix[i] = (T*) new T[size];
    }
  }

  //Метод очистки памяти
  void clear() {
    for (int i = 0; i < size; i++) {
      delete[] matrix[i];
    }
    delete[] matrix;
  }

  void clear(T** arr, int size)
  {
    for (int i = 0; i < size; i++)
      delete[] arr[i];
    delete[] arr;
  }
public:
  //Конструктор без аргументов
  Matrix()
  {
    //Задаем размер
    this->size = 3;
    //Выделяем память
    set();
    //Заполняем матрицу
    full(0);
  }
  //Конструктор заполняющий матрицу переданным числом
  Matrix(T n) {
    //Задаем размер
    this->size = 3;
    //Выделяем память
    set();
    //Заполняем матрицу
    full(n);

    //cout << "Determinant: " << det(this->matrix, size) << endl;
  }
    
  //Метод заполнения матрицы
  void full(T n) {
    for (int i = 0; i < size; i++)
    {
      for (int j = 0; j < size; j++)
      {
        this->matrix[i][j] = n;
      }
    }
  }

  //Метод для вывода информации о матрице
  void print() {
    string result = "Size: " + to_string(size) +  "\r\n[\r\n";

    for (int i = 0; i < size; i++)
    {
      result += "\t";

      for (int j = 0; j < size; j++)
      {
        result += to_string(matrix[i][j]) + " ";
      }

      result += "\r\n";
    }
    
    result += "]\r\n";

    cout << result;
  }

  //Геттер
  int getSize() {
    return size;
  }
  
  //Метод изменения элеметнов матрицы
  void put(int i, int j, T n) {
    //Проверка на соответствие
    if ((i < 0) || (i >= size) || (j < 0) || (j >= size)) {
      return;
    }
      
    matrix[i][j] = n;
  }

  T get(int i, int j) {
    return matrix[i][j];
  }

  //создать копию массива
  T** clone(T** arr, int n)
  {
    T** newArr = new T* [n];
    for (int row = 0; row < n; row++)
    {
      newArr[row] = new T[n];
      for (int col = 0; col < n; col++)
        newArr[row][col] = arr[row][col];
    }
    return newArr;
  }

  double det(T** mat, int n) //квадратная матрица размера n*n
  {
    print();
    T** B = clone(mat, n);
    //приведение матрицы к верхнетреугольному виду
    for (int i = 0; i < n - 1; i++)
      for (int j = i + 1; j < n; j++)
      {
        cout << i << "-i, " <<  B[i][i] << endl;
        double coeff = -B[j][i] / B[i][i]; //метод Гаусса
        cout << coeff << endl << endl; 
        for (int k = i; k < n; k++)
          B[j][k] += B[i][k] * coeff;
      }
    //Рассчитать определитель как произведение элементов главной диагонали
    double Det = 1;
    for (int i = 0; i < n; i++)
      Det *= B[i][i];
    //Очистить память
    clear(B, n);
    return Det;
  }

  //Работа с операторами
  T* operator[] (int n) {
    T* arr = new T [size];

    for (int i = 0; i < size; i++)
    {
      arr[i] = matrix[n][i];
    }

    return arr;
  }

  Matrix operator= (Matrix m) {

    clear();

    // Копирование данных M <= _M
    size = m.getSize();


    set();

    //Заполним значениями
    for (int i = 0; i < size; i++) {
      for (int j = 0; j < size; j++) {
        matrix[i][j] = m[i][j];
      }
    }			

    return *this;
  }
  
  Matrix operator+ (Matrix m) {

    Matrix<T> newMatrix;

    for (int i = 0; i < size; i++)
    {
      for (int j = 0; j < size; j++)
      {
        newMatrix.put(i, j, matrix[i][j] + m[i][j]);
      }
    }

    return newMatrix;
  }

  Matrix operator- (Matrix m) {

    Matrix<T> newMatrix;
    
    for (int i = 0; i < size; i++)
    {
      for (int j = 0; j < size; j++)
      {
        newMatrix.put(i, j, matrix[i][j] - m[i][j]);
      }
    }


    return newMatrix;
  }

  Matrix operator* (Matrix m) {

    Matrix<T> newMatrix;

    int sum = 0;

    for (int i = 0; i < size; i++)
    {

      for (int j = 0; j < size; j++)
      {
        sum = 0;

        for (int k = 0; k < size; k++)
        {
          sum += matrix[i][k] * m[k][j];
        }

        newMatrix.put(i, j, sum);
      }
    }
    
    return newMatrix;
  }

  bool operator== (Matrix m) {
    for (int i = 0; i < size; i++)
    {
      for (int j = 0; j < size; j++)
      {
        if (matrix[i][j] != m[i][j])
        {
          return false;
        }
      }
    }

    return true;
  }

  //Деструктор - освобождает память, выделенную для матрицы
  ~Matrix()
  {
    clear();
  }
};


int main()
{
  Matrix<int> matrix(1);
  matrix.print();

  matrix.put(0, 0, 3);
  matrix.print();
  
  //cout << matrix[0][1] << endl;

  Matrix<int> matrix2(2);
  matrix2.print();

  Matrix<int> matrix3;

  matrix3 = matrix * matrix2;
  matrix3.print();

  matrix2.full(2);
  matrix3.full(2);

  if (matrix2 == matrix3)
  {
    cout << "Matrices are equal" << endl;
  } else {
    cout << "Matrices are not equal" << endl;
  }

  //cout << "Determinant: " << matrix.getDeterminant() << endl;

  return 0;
}

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vasily Bannikov, 2020-12-20
@vabka

Take a debugger and execute the code step by step.
Instead of you, no one here will deal with debugging

A
Alexander Ananiev, 2020-12-20
@SaNNy32

What happens in the string
double coeff = -B[j][i] / B[i][i];
if B[i][i] is equal to zero?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question