'Recursive function to check if two matrices are equal using pointers

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;
}


Solution 1:[1]

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)

Solution 2:[2]

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;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Some programmer dude
Solution 2