0

I am trying to implement a class for matrices in linear algebra. Whenever I call the determinant() function from this class, there is a segmentation fault. However, this segmentation fault only occurs for matrices with side length greater than 2. I know that the instantiation of the class isn't causing the problem, so maybe it has something to do with templates?

Here is the code for the class (in C++):

template<typename Number> 
class linear_matrix {
    
    private:
    
        std::size_t side;
        vector<vector<Number>> m;
        
        Number det(vector<vector<Number>> mat, size_t n) {
            if (n == 1) return mat[0][0];
            Number total = 0;
            for (size_t i = 0; i < side; i++) {
                vector<vector<Number>> v(n-1);
                Number factor = mat[0][i] * pow(-1, i);
                for (size_t j = 1; j < side; j++) {
                    for (size_t k = 0; k < side; k++) {
                        if (k != i) {
                            v[j-1].push_back(mat[j][k]);
                        }
                    }
                }
                total += factor * det(v, n-1);
            }
            return total;
        }
        
    public:
    
        linear_matrix(size_t sz) { //constructor 
            side = sz;
            m.resize(side);
            for (std::size_t i = 0; i < side; i++) m[i].resize(side);
            static_assert(is_integral<Number>::value, "Numeric type required.");
            for (std::size_t i = 0; i < side; i++) for (std::size_t j = 0; j < side; j++) m[i][j] = 0;
        }
        
        linear_matrix(size_t sz, vector<vector<Number>> v) { //turns vector argument into matrix
            side = sz;
            m.resize(side);
            for (std::size_t i = 0; i < side; i++) m[i].resize(side);
            static_assert(is_integral<Number>::value, "Numeric type required.");
            for (std::size_t i = 0; i < side; i++) for (std::size_t j = 0; j < side; j++) m[i][j] = v[i][j];
        }
        
        std::size_t side_length() {
            return side;
        }
        
        Number determinant() {
            return det(m, side);
        }
        
};

I know that the function itself isn't the problem, because I have implemented a similar function that works fine for matrices larger than 2, like so:

int determinant(vector<vector<int>>& matrix) {
    if (matrix.size() == 1) return matrix[0][0];
    int total = 0;
    for (int i = 0; i < matrix.size(); i++) {
        int factor = pow(-1, i) * matrix[0][i];
        vector<vector<int>> v(matrix.size() - 1);
        for (int j = 1; j < matrix.size(); j++) {
            for (int k = 0; k < matrix.size(); k++) {
                if (k != i) v[j-1].push_back(matrix[j][k]);
            }
        }
        total += factor * determinant(v);
    }
    return total;
}

Is the class using memory it shouldn't be using, or is the template acting weird?

  • Let's see a [mcve]. `if (matrix.size() == 1) return matrix[0][0];` -- This fails if `matrix[0]` is empty, both with the "working" code and the non-working code. – PaulMcKenzie Jul 23 '22 at 04:20
  • `matrix[0][i]`--> `matrix.at(0).at(i)` -- Make that change there and to all the places you are accessing `matrix` using `[]`. Then I can almost bet you will now get an `std::out_of_range` exception instead of a seg fault. If so, then you need to figure out which `at()` call caused the exception. And also this: `v[j-1]` --> `v.at(j-1)` and in similar places where you're doing this. – PaulMcKenzie Jul 23 '22 at 04:23

0 Answers0