@Urilobus

В каком из конструкторов ошибка?

Пытаюсь отловить ошибку при выполнении функции Kramer_solver. В начале функции перемещающее присваивание работает без нареканий. В конце функции аналогичная строка выдаёт ошибку при попытке очистить старую память в Intermid_Mat (оставил комментарий в перемещающем присваивании в месте ошибки).

Intermid_Mat объект самописного класса матриц, где Mat_1 является указателем на указатель.
Функции Determinant (Matrix Inp_Mat) работает с копией Inp_Mat.
Код
Matrix::Matrix()
    :rows_num(0), cols_num(0), Mat_1(nullptr)
{
    std::cout << "Конструктор для " << this << std::endl;
};

Matrix::Matrix(int n, int m)
{
    std::cout << "Конструктор для " << this << std::endl;
    rows_num = n;
    cols_num = m;

    Mat_1 = new double* [n];   //Создание столбца указателей (Динамическая память)
    if (Mat_1 == NULL)
    {
        std::cout << "\n Не хватает оперативной памяти под строки"; 
        exit(1);
    }
    for (int i = 0; i < n; i++)
    {
        Mat_1[i] = new double[m];
        if (Mat_1[i] == NULL)
        {
            std::cout << "\n Не хватает оперативной памяти под столбцы"; 
            exit(1);
        }
    }

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
        {
            Mat_1[i][j] = 0;
        }

};

//Конструктор копирования
Matrix::Matrix(const Matrix& Mat)
{
    this->rows_num = Mat.rows_num;
    this->cols_num = Mat.cols_num;
    Mat_1 = new double* [Mat.rows_num];
    for (int i = 0; i < Mat.rows_num; i++)
    {
        Mat_1[i] = new double[Mat.cols_num];
        for (int j = 0; j < Mat.cols_num; j++) Mat_1[i][j] = Mat(i, j);
    }
    std::cout << "Копирование " << this << std::endl;

}

//Конструктор перемещения
Matrix::Matrix(Matrix&& other)
    :rows_num(0), cols_num(0), Mat_1(nullptr)
{
    std::swap(rows_num, other.rows_num);
    std::swap(cols_num, other.cols_num);
    std::swap(Mat_1, other.Mat_1);
    std::cout << "Перемещение " << this << std::endl;
    std::cout << "Результат перемещения" << std::endl;
    this->Matrix_out();
}

//Копирующее присванивание
Matrix& Matrix::operator = (const Matrix& other)
{
    double** Mat_copy = new double* [other.Get_rows_num()]; //Выделение новой памяти в которую копируем
    for (int i = 0; i < other.Get_rows_num(); i++) {        //Выделение памяти и заполнение её элементами
        Mat_copy[i] = new double[other.Get_cols_num()];
        for (int j = 0; j < other.Get_cols_num(); j++) Mat_copy[i][j] = other(i, j);
    }
    std::cout << "Освобождаемая матрица" << std::endl;
    this->Matrix_out();
    for (int i = 0; i < rows_num; i++) delete[] this->Mat_1[i];      //Освобождение старой памяти со старыми данными
    delete[] Mat_1;
    Mat_1 = Mat_copy;                                       //Переназначаем указатели на память выделенную и заполненную в 1й строке
    for (int i = 0; i < rows_num; i++) Mat_1[i] = Mat_copy[i];
    this->rows_num = other.Get_rows_num();
    this->cols_num = other.Get_cols_num();
    std::cout << "Копирующее присваивание\t" << &other << "в" << this << std::endl;
    return *this;
}

//Перемещающее присваивание
Matrix& Matrix::operator = (Matrix&& other)
{
    if (this != &other)
    {
        std::cout << "Замещаемая матрица" << std::endl;
        this->Matrix_out();
        for (int i = 0; i < rows_num; i++) delete[] Mat_1[i];   //Выдаёт ошибку тут
        delete[] Mat_1;
        this->Mat_1 = other.Mat_1;
        this->rows_num = other.rows_num;
        this->cols_num = other.cols_num;
        other.Mat_1 = nullptr;
        other.rows_num = 0;
        other.cols_num = 0;
        std::cout << "Перемещающее присваивание " << this << std::endl;
    }
    return *this;
}

// Деструктор
Matrix::~Matrix()
{
    std::cout << "Деструктор для " << this << std::endl;
    this->Matrix_out();
    if (Mat_1) {
        for (int i = 0; i < rows_num; i++) delete[] Mat_1[i];
    }
    delete[] Mat_1;
    rows_num = 0;
    cols_num = 0;
};

//Inp_Mat матрица 3x4, Dets вектор для вывода результатов
void Kramer_solver(Matrix& Inp_Mat, std::vector<double> &Dets)
{
    Matrix Intermid_Mat(Inp_Mat.Get_rows_num(), Inp_Mat.Get_cols_num() - 1);
//Перемещающее присваивание срабатывает
    Intermid_Mat = Del_Column(Inp_Mat, Inp_Mat.Get_cols_num());              
    Intermid_Mat.Matrix_out();
    double Sys_Det = (Determinant(Intermid_Mat));
    Intermid_Mat.Matrix_out();
    for (int i = 0; i < Intermid_Mat.Get_cols_num(); i++)
    {
        for (int j = 0; j < Inp_Mat.Get_rows_num(); j++)
        {
            Intermid_Mat(j, i) = Inp_Mat(j, Inp_Mat.Get_cols_num() - 1);
            std::cout << Inp_Mat(j,Inp_Mat.Get_cols_num()-1)<<"\t"<< Intermid_Mat(j, i)<< std::endl;
        }
        Intermid_Mat.Matrix_out();
        Dets.push_back(Determinant(Intermid_Mat) / Sys_Det);
//Перемещающее присваивание не срабатывает, ошибка при попытке очистить старые данные в Intermid_Mat
        Intermid_Mat = Del_Column(Inp_Mat, Inp_Mat.Get_cols_num());             
    }
}
  • Вопрос задан
  • 85 просмотров
Пригласить эксперта
Ответы на вопрос 1
maaGames
@maaGames
Погроммирую программы
Перед вот этой строкой
for (int i = 0; i < rows_num; i++) delete[] Mat_1[i];   //Выдаёт ошибку тут

нужно проверять if( Mat_1 != nullptr )

А вот после этой строки цикл не нужен, там самоприсваивание происходит внутри одного массива
Mat_1 = Mat_copy;                                       //Переназначаем указатели на память выде
Ответ написан
Ваш ответ на вопрос

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

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