0

I'm currently working on a program that is supposed to ask user for some data and create 2 matrix based on them. Later on program should also have option to calculate determinant for these matrix. I wanted to have this done in function (int determinant), however when i try to use it for matrix 3x3 or bigger the program crush with error (Process returned -1073741819 (0xC0000005) execution time : 23.503 s)

What might be causing it?

#include <iostream>
#include <windows.h>
#include <cstdlib>
#include <time.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>

using namespace std;

void inputdata (int&,int&,int&,int&,int&,int&);
void printmatrix (int**,int&,int&);
int determinant(int**, int);
bool ifmatsquare (int, int);

int main()
{
    int rows1=0,rows2=0,colm1=0,colm2=0,matmin=0,matmax=0;
    char menuoption;


    while (true){

    inputdata(rows1,rows2,colm1,colm2,matmin,matmax);

    system("cls");


    int **matrix1(0);
    int **matrix2(0);

    matrix1 = new int *[rows1];
    matrix2 = new int *[rows2];

   srand(time(NULL));

    for(int  i = 0; i <rows1; i++){
        matrix1[i] = new int[colm1];
        for(int j = 0; j <colm1; j++){
            matrix1[i][j] = rand()%(matmax-matmin+1) + matmin;;
        }
    }


    for(int i = 0; i <rows2; i++){
        matrix2[i] = new int[colm2];
        for(int j = 0; j <colm2; j++){
            matrix2[i][j] = rand()%(matmax-matmin+1) + matmin;;
        }
    }

    for (bool menu=true; menu==true;){

    printmatrix(matrix1, rows1, colm1);
    cout<< endl;
    printmatrix(matrix2, rows2, colm2);
    cout<< endl;
    cout<< endl;

    cout<< "MENU \n" <<endl;
    cout<< "1: XXX" <<endl;
    cout<< "2: XXX" <<endl;
    cout<< "3: Calculate Determinant" <<endl;
    cout<< "4: XXX" <<endl;
    cout<< "5: Reset program" <<endl;
    cout<< "6: Exit program" <<endl;
    cout<< endl;

    menuoption = getch();

    switch(menuoption){
    /*case '1':
        //jakis kod
        break;
    */
    case '3':
        char mat1or2;
        cout<< "Matrix 1 or 2: ";
        do {
        mat1or2 = getch();
        } while ((mat1or2!='1') && (mat1or2!='2'));

        if ((mat1or2=='1')&&(ifmatsquare(rows1,colm1)==true))
        cout<<"\nDeterminant for matrix 1 is "<<determinant(matrix1, rows1)<<endl;
        else if ((mat1or2=='2')&&(ifmatsquare(rows2,colm2)==true)){
        cout<<"\nDeterminant for matrix 2 is "<<determinant(matrix2, rows2)<<endl;
        }

        cout<< "Press any key to return to menu";
        getch();
        break;

    case '5':
        menu=false;
        break;

    case '6':
        delete []matrix1;
        delete []matrix2;
        exit(0);
        break;

    default:
        cout<< "No such option, press any key to reurn to menu!"<<endl;
        getch();
        break;
    }

    system("cls");
}

    delete []matrix1;
    delete []matrix2;

}

    return 0;
}

void inputdata (int &r1,int &r2,int &c1,int &c2,int &mmin, int &mmax){
    cout << "Give number of rows for matrix 1" << endl;
    cin >> r1;

    cout << "Give number of columns for matrix 1" << endl;
    cin >> c1;

    do{
        cout << "Give number of rows for matrix 2 (should be the same as columns for matrix 1)" << endl;
        cin >> r2;
        } while(r2!=c1);

    cout << "Give number of columns for matrix 2" << endl;
    cin >> c2;

    cout << "Give MIN value for matrix" << endl;
    cin >> mmin;

    do{
        cout << "Give MAX value for matrix" << endl;
        cin >> mmax;
    } while(mmax<mmin);
}

void printmatrix(int **a, int &rows, int &colm){
        for (int x = 0; x < rows; x++)
        {
            for (int y = 0; y < colm; y++)
            {
                printf("%4d", a[x][y]);
            }
            printf("\n");
        }
    }

bool ifmatsquare(int row, int col){

    if (row == col){
        cout<<endl;
        return true;}
    else
        cout<<"Determinant can be caclucated only for square matrix"<<endl;
        return false;
}

int determinant(int **a, int size) {
    int det = 0;
    int **submatrix(0);
    if (size == 2)
        return ((a[0][0] * a[1][1]) - (a[1][0] * a[0][1]));
    else {
        for (int x = 0; x < size; x++) {
            int subi = 0;
            for (int i = 1; i < size; i++) {
                int subj = 0;
                for (int j = 0; j < size; j++) {
                    if (j == x)
                    continue;
                    submatrix[subi][subj] = a[i][j];
                    subj++;
                    }
                subi++;
            }
            det = det + (pow(-1, x) * a[0][x] * determinant(submatrix, size - 1));
        }
    }
    return det;
}
Greg
  • 1
  • 1
  • 1
    Unrelated: [A kinder and gentler (and probably much faster) Matrix](https://stackoverflow.com/a/2076668/4581301) – user4581301 Jan 29 '20 at 22:52
  • 1
    Sidenote: `pow(-1, x)` is an extremely heavyweight way to flip a sign bit for evens and odds unless the compiler recognizes what you are doing and preplaces it. `pow` is designed to compute really nasty like pi to the power of e. Testing the last bit (any decent compiler would optimize `x%2`) and returning 1 or -1 would be a lot quicker and cleaner. – user4581301 Jan 29 '20 at 23:00
  • On topic you've got an access violation (error 0xC0000005) so your program likely marched outside of valid memory. Make certain that no array accesses breach the array and since `determinant` is recursive make sure the recursion ends where you think is should. Use your development environment's debugger to help track the recursion and if you take advantage of the smarter matrix pitched in the first comment the `std::vector::at` method can help catch buffer breaches. – user4581301 Jan 29 '20 at 23:37
  • Memory is not reserved for `submatrix` in `determinant` – Damien Jan 30 '20 at 12:01
  • @Damien - would you be able to advise where and how it should be done? I'm currently trying to debug it (putting cout<<"Text X" to check where it is going) by with little success. – Greg Jan 30 '20 at 13:21
  • In main(), you made memory reservation for `matrix1` and `matrix2`. You could do the same the `submatrix`. Pay attention not forgetting to `delete[]` at the end. A better solution would be to use `std::vector>` or even better a `Matrix` class as proposed by @user4581301 – Damien Jan 30 '20 at 13:45

1 Answers1

0

Thank you for your help.

You were right that I not declared space for submatrix

I modified my function and it now looks like below (and works as intended)

int determinant(int **a, int matsize) {
int det = 0;
int** submatrix = new int*[matsize];
for (int i = 0; i < matsize; ++i)
submatrix[i] = new int[matsize];

if (matsize == 1)
    return a[0][0];
else if (matsize == 2)
    return ((a[0][0] * a[1][1]) - (a[1][0] * a[0][1]));
else {
    for (int x = 0; x < matsize; x++) {
    int subi = 0;
    for (int i = 1; i < matsize; i++) {
    int subj = 0;
    for (int j = 0; j < matsize; j++) {
    if (j == x)
    continue;
    submatrix[subi][subj] = a[i][j];
    subj++;
    }
    subi++;
    }
    det = det + (pow(-1, x) * a[0][x] * determinant(submatrix, matsize - 1));
    }
    }

    for (int i = 0; i < matsize; ++i)
    delete [] submatrix[i];
    delete [] submatrix;

    return det;
}
Greg
  • 1
  • 1