0

I have written this program to check if two matrices are equal or not. Whenever I run it, it gives me segmentation faults.

int equal(int** matrix1, int** matrix2, int row, int col) {
    if(col < 0) {
        col = row;
        row--;
    }
    if(row < 0) {
        return 1;
    }
    if(matrix1[row][col] == matrix2[row][col]) {
        return equal(matrix1, matrix2, row, col-1);
    }
    else {
        return 0;
    }
}

int main() {

    int **ptr1 = new int*[3];
    int **ptr2 = new int*[3];
    for(int i=0; i<3; i++) {
        ptr1[i] = new int[3];
        ptr2[i] = new int[3];
    }

    ptr1[0][0] = 1;
    ptr1[0][1] = 2;
    ptr1[0][2] = 2;
    ptr1[1][0] = 4;
    ptr1[1][1] = 5;
    ptr1[1][2] = 6;
    ptr1[2][0] = 7;
    ptr1[2][1] = 8;
    ptr1[2][2] = 9;

    ptr2[0][0] = 1;
    ptr2[0][1] = 2;
    ptr2[0][2] = 2;
    ptr2[1][0] = 4;
    ptr2[1][1] = 5;
    ptr2[1][2] = 6;
    ptr2[2][0] = 7;
    ptr2[2][1] = 8;
    ptr2[2][2] = 9;

    cout << equal(ptr1, ptr2, 3, 3);

    return 0;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    You seem to know that for array or pointers, `p[i]` is equal to `*(p + i)`. So why don't you use the much easier to read and understand array-indexing syntax in your function? So you do e.g. `matrix1[row][col]` instead? – Some programmer dude Mar 22 '22 at 09:16
  • You should not use `new`/`delete` manually in c++. Also seems that a fix sized array would suffice for your case. – πάντα ῥεῖ Mar 22 '22 at 09:18
  • 1
    Aside boundary issue. The logic never checks for all of the elements. It only checks for `[3][3]` to `[3][0]` and `[3][0]` to `[0][0]`. – Louis Go Mar 22 '22 at 09:24
  • You're passing the number of elements to the function, but the function wants the indices of an element. – molbdnilo Mar 22 '22 at 09:41

2 Answers2

2

Your initial call of the equal function is

equal(ptr1,ptr2,3,3)

That passes the size of the matrix as the row and col arguments, not the top indexes which is what the function expects.

That means when you do e.g. matrix1[row][col] you will go out of bounds and have undefined behavior.

Either change your logic in the function to always subtract one from the row and col values. Or (much simpler) change the initial call to use the top index instead of the size:

equal(ptr1,ptr2,2,2)
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

There are multiple issues in your code:

  1. You pass the lenghts of matrix to equal() while using them as index in the function. Apparently matrix[3][3] cause out of bound access.
  2. Compare logic only change row and col without checking every elements. You checked only 5 elements instead of all of them.
  3. Use recursive approach when logic is easier to handle and the use cases don't get your stack overflow. However this case would be easier to read if you use iteration approach.

Assume inputs are correct (col = 2 and row = 2). Shows as below, where [O] is checked but [X] isn't.

   3  2  1
  [O][O][O]  // 1. [2][2]
4 [O][X][X]  // 2. [2][1]
5 [O][X][X]  // 3. [2][0]
             // 4. [1][0]
             // 5. [0][0]

The easiest way to compare a matrix should be using std::vector or std::array. Live Demo

#include <iostream>
#include <array>
int main()
{
    std::array<std::array<int,3>, 3> m1{{{1,2,3},{1,2,3},{1,2,3}}};
    std::array<std::array<int,3>, 3> m2{{{1,2,3},{1,2,3},{1,2,3}}};
    std::array<std::array<int,3>, 3> m3{{{3,3,3},{1,2,3},{1,2,3}}};
    std::cout << "m1 m2 compare result:" << std::boolalpha << (m1 == m2) << std::endl; 
    std::cout << "m2 m3 compare result:" << std::boolalpha << (m3 == m2) << std::endl; 

    return 0;
}

Louis Go
  • 2,213
  • 2
  • 16
  • 29