Home > Enterprise >  Segmentation Fault During Matrix Multiplication
Segmentation Fault During Matrix Multiplication

Time:11-05

I am new to C coding, and am trying to implement standard matrix multiplication. My code works fine for square matrices, but refuses to accept a column vector. Here is my attempt at the code. Any help would be much appreciated.

//---------------------------------------IMPORTING NECESSARY C PACKAGES AND DEFINING EXECUTION CONSTANTS-------------------------------------------//
#include <stdio.h> // Standard input output library
#include <math.h> // Mathematical function library
#include <stdlib.h> // General purpose standard library

#define true 1
#define false 0
typedef long double numeric; // Using the long double datatype to avoid overflows during computations
//-------------------------------------------------------------------------------------------------------------------------------------------------//

//----------------------------------------------------------------FUNCTION DECLERATION-------------------------------------------------------------//
numeric **create_matrix(int x, int y); // To dynamically allocate memory and create a matrix
void input_matrix(numeric **matrix, int m, int n); // To accept a matrix
void print_matrix(numeric **l, int x, int y); // To print a matrix
numeric **standard_matrix_multiplication(int m, int n, int l); // To multiply two matrices
//-------------------------------------------------------------------------------------------------------------------------------------------------//

//------------------------------------------------------------------DRIVER CODE--------------------------------------------------------------------//
int main(int argc, char *argv[]) {
  int m, n, l; int choice;
  printf("Enter the matrix operation to be performed using the corresponding index number.\n");
  printf("\n");
  printf("1.\tMatrix Multiplication");
  printf("\n");
  scanf("%d", &choice);

  switch(choice) {
    case 1 :
    printf("Enter the number of rows in the first matrix\n");
    scanf("%d", &m);
    printf("Enter the number of columns in the first matrix\n");
    scanf("%d", &n);
    printf("Enter the number of columns in the second matrix\n");
    scanf("%d", &l);
    printf("Enter both matrices.\n");
    numeric **matrix_x;
    matrix_x = create_matrix(m, l);
    matrix_x = standard_matrix_multiplication(m, n, l);
    print_matrix(matrix_x, m, l);
    break;
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//

//----------------------------------------------------------MATRIX MULTIPLICATION IMPLEMENTATIONS--------------------------------------------------//
numeric **standard_matrix_multiplication(int m, int n, int l) {
  numeric **matrix_a; numeric **matrix_b; numeric **matrix_k;
  matrix_a = create_matrix(m, n);
  matrix_b = create_matrix(n, l);
  matrix_k = create_matrix(m, l);
  input_matrix(matrix_a, m, n);
  print_matrix(matrix_a, m, n);
  input_matrix(matrix_b, n, l);
  for(int i = 0; i < m; i  ) {
    for (int j = 0; j < n; j   ) {
      for (int k = 0; k < l; k  ) {
        matrix_k[i][j]  = matrix_a[i][k] * matrix_b[k][j];
      }
    }
  }
  return matrix_k;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//

//---------------------------------------------------------------HELPER FUNCTIONS------------------------------------------------------------------//
numeric **create_matrix(int x, int y) {
  numeric **matrix = (numeric**)malloc(x * sizeof(numeric*)); // Dynamically creating an array of pointers
  for (int i = 0; i < y; i  ) {
    matrix[i] = (numeric*)malloc(y * sizeof(numeric)); // Dynamically allocating memory for each columns of the matrix
  }
  return matrix;
}

void input_matrix(numeric **matrix, int m, int n) {
  printf("Enter the elements of the matrix, row wise.\n"); // Instructing the user on matrix entry
  printf("For example, to enter the matrix\n");
  printf("\t\t1\t2\n");
  printf("\t\t3\t4\n");
  printf("enter 1, 2, 3, and 4 in that order.\n");

  for (int i = 0; i < m; i  ) { // Iterating through the rows and columns of the matrix
    for (int j = 0; j < n; j  ) {
      scanf("%Lf", &matrix[i][j]); // Accepting each element
    }
  }
}

void print_matrix(numeric **l, int x, int y) { // To print a matrix
    for (int i = 0; i < x; i  ) {
        for (int j = 0; j < y; j  ) {
            printf("%0.10Lf\t", l[i][j]); // Printing numeric type values
        }
    printf("\n");
    }
  printf("\n");
}

As of now, I have only written one switch case, and that is for matrix multiplication. So I chose 1. I gave 2, 1, 2 as my inputs for the number of rows in the first matrix, number of columns in the first matrix, and number of columns in the second matrix respectively. I have given a print statement in line 52, and it isn't executing it for the above input, giving a segmentation fault instead. Could someone please help me out?

CodePudding user response:

Yes there are some issues with your code that gives segfault error during runtime. The Matrix multiplication logic part of the code needs to be corrected as follows

for(int i = 0; i < m; i  ) {
for (int j = 0; j < l; j   ) {
  for (int k = 0; k < n; k  ) {
    matrix_k[i][j]  = matrix_a[i][k] * matrix_b[k][j];

because k should iterate till the no of columns in 1st matrix which is n but not till l.

And there is a slight correction needed in create_matrix function. You use y (i.e. no of columns in the matrix) in your for instead of x (no of rows in matrix).

If x < y, you end up outside of the memory you allocated.

If x > y, you end up with uninitialized pointers.

So change it as follows

for (int i = 0; i < x; i  ) {
matrix[i] = (numeric*)malloc(y * sizeof(numeric)); 

After these corrections try executing the code, you should get the expected results without any segfault errors

Here is the complete working code

#include <stdio.h> // Standard input output library
#include <math.h> // Mathematical function library
#include <stdlib.h> // General purpose standard library

#define true 1
#define false 0
typedef long double numeric; // Using the long double datatype to avoid overflows during computations
//-------------------------------------------------------------------------------------------------------------------------------------------------//

//----------------------------------------------------------------FUNCTION DECLERATION-------------------------------------------------------------//
numeric **create_matrix(int x, int y); // To dynamically allocate memory and create a matrix
void input_matrix(numeric **matrix, int m, int n); // To accept a matrix
void print_matrix(numeric **l, int x, int y); // To print a matrix
numeric **standard_matrix_multiplication(int m, int n, int l); // To multiply two matrices
//-------------------------------------------------------------------------------------------------------------------------------------------------//

//------------------------------------------------------------------DRIVER CODE--------------------------------------------------------------------//
int main(int argc, char *argv[]) {
  int m, n, l; int choice;
  printf("Enter the matrix operation to be performed using the corresponding index number.\n");
  printf("\n");
  printf("1.\tMatrix Multiplication");
  printf("\n");
  scanf("%d", &choice);

  switch(choice) {
    case 1 :
    printf("Enter the number of rows in the first matrix\n");
    scanf("%d", &m);
    printf("Enter the number of columns in the first matrix\n");
    scanf("%d", &n);
    printf("Enter the number of columns in the second matrix\n");
    scanf("%d", &l);
    printf("Enter both matrices.\n");
    numeric **matrix_x;
    matrix_x = create_matrix(m, l);
    matrix_x = standard_matrix_multiplication(m, n, l);
    print_matrix(matrix_x, m, l);
    break;
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//

//----------------------------------------------------------MATRIX MULTIPLICATION IMPLEMENTATIONS--------------------------------------------------//
numeric **standard_matrix_multiplication(int m, int n, int l) {
  numeric **matrix_a; numeric **matrix_b; numeric **matrix_k;
  matrix_a = create_matrix(m, n);
  matrix_b = create_matrix(n, l);
  matrix_k = create_matrix(m, l);
  input_matrix(matrix_a, m, n);
  print_matrix(matrix_a, m, n);
  input_matrix(matrix_b, n, l);
  //print_matrix(matrix_b, n, l);
  for(int i = 0; i < m; i  ) {
    for (int j = 0; j < l; j   ) {
      for (int k = 0; k < n; k  ) {
        matrix_k[i][j]  = matrix_a[i][k] * matrix_b[k][j];

      }
    }
  }
  return matrix_k;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//

//---------------------------------------------------------------HELPER FUNCTIONS------------------------------------------------------------------//
numeric **create_matrix(int x, int y) {
  numeric **matrix = (numeric**)malloc(x * sizeof(numeric*)); // Dynamically creating an array of pointers
  for (int i = 0; i < x; i  ) {
    matrix[i] = (numeric*)malloc(y * sizeof(numeric)); // Dynamically allocating memory for each columns of the matrix
  }
  return matrix;
}

void input_matrix(numeric **matrix, int m, int n) {
  printf("Enter the elements of the matrix, row wise.\n"); // Instructing the user on matrix entry
  printf("For example, to enter the matrix\n");
  printf("\t\t1\t2\n");
  printf("\t\t3\t4\n");
  printf("enter 1, 2, 3, and 4 in that order.\n");

  for (int i = 0; i < m; i  ) { // Iterating through the rows and columns of the matrix
    for (int j = 0; j < n; j  ) {
      scanf("%Lf", &matrix[i][j]); // Accepting each element
    }
  }
}

void print_matrix(numeric **l, int x, int y) { // To print a matrix
    for (int i = 0; i < x; i  ) {
        for (int j = 0; j < y; j  ) {
            printf("%0.10Lf\t", l[i][j]); // Printing numeric type values
        }
    printf("\n");
    }
  printf("\n");
}

CodePudding user response:

You are not allocating enough memory for matrix_k. You are allocating memory for m rows and l columns, but you are trying to access m rows and n columns. You need to allocate memory for m rows and n columns. You can do this by changing the line

matrix_k = create_matrix(m, l);

to

matrix_k = create_matrix(m, n);

This is the same problem you had in your other question.

  • Related