Segfault 11 when trying to multiply 2 matrices - c

I'm trying to multiply 2 dynamically allocated arrays. I'm having 2 problems:
When I try unequal sized arrays like [2],[3] and [3],[2] I got a segmentation fault 11, and after staring at my allocations I still can't figure out why.
My final array is formatted with the correct rows and columns, but it displays all 0's.
I'm assuming that this is because I didn't allocate the memory correctly.
-
#include <stdio.h>
#include <stdlib.h>
int main()
{
int **a, **b, **c; //pointers to arrays
int m1_r,m1_c,m2_r,m2_c; //declaring arrays
int i,j,k;
printf("\n");
again://repeat if first matrixes are bad
printf("Enter rows and columns for the first matrix.\n");//first matrix
scanf("%d%d" ,&m1_r,&m1_c);
printf("Enter rows and Columns for the second matrix.\n");//second matrix
scanf("%d%d",&m2_r,&m2_c);
if(m1_c!=m2_r) {
printf("You tried to break my code. Nice try.");
goto again;
}
//memory for first matrix
a = malloc(m1_r * sizeof(int *));
for(i=0; i < m1_r; i++) {
a[i] = malloc(m1_c * sizeof(int));
}
//memory for second matrix
b = malloc(m2_r * sizeof(int *));
for(i=0; i < m2_r; i++) {
b[i] = malloc(m2_c * sizeof(int));
}
//memory for 3rd matrix
c = malloc(m1_r * sizeof(int *));
for(i=0; i < m2_r; i++) {
c[i] = malloc(m2_c * sizeof(int));
}
//input 1st matrix
printf("Enter the numbers of the first matrix.\n");
for (i=0; i<m1_r; i++) {
for (j = 0; j<m1_c; j++) {
scanf("%d", &a[i][j]);
}
}
//input 2nd matrix
printf("Enter the second of the first matrix.\n");
for (i=0; i<m1_r; i++) {
for (j = 0; j<m1_c; j++) {
scanf("%d", &b[i][j]);
}
}
printf("\n");
printf("1st matrix looks like this:\n");
//print 1st matrix
for (i=0; i<m1_r; i++) {
for (j = 0; j<m1_c; j++) {
printf("%d\t", a[i][j]);
}
printf("\n");
}
//print 2nd matrix
printf("\n");
printf("2nd matrix looks like this:\n");
//print 2st matrix
for (i=0; i<m2_r; i++) {
for (j = 0; j<m2_c; j++) {
printf("%d\t", b[i][j]);
}
printf("\n");
}
//initialize result matrix to 0
for(i=0; i<m2_r; i++)
for(j=0; j<m2_c; j++) {
c[i][j]=0;
}
//multipication
for(i=0; i<m1_r; i++)
for(j=0; j<m2_c; j++)
for(k=0; k<m1_c; k++) {
c[i][j]+= a[i][k]*b[k][j];
}
//print result
printf("\nThe result of the matrix multiplication is:");
for(i=0; i<m1_r; i++) {
printf("\n");
for(k=0; k<m2_c; k++) {
printf("%d\t", c[i][j]);
}
}
printf("\n");
return 0;
}

You allocate the wrong amount of memory for the third matrix:
c = malloc(m1_r * sizeof(int *));
for(i=0; i < m2_r; i++)
The loop count should be the same as the number of pointers you malloc.
To avoid this sort of error, consider making a function which you pass in the dimensions and it returns the pointer.
Later on, you overwrite its bounds using different indices again:
for(i=0;i<m2_r;i++)
for(j=0;j<m2_c;j++)
{
c[i][j]=0;
}
Then you overwrite the bounds of b (it was m2_r and m2_c):
for (i=0; i<m1_r; i++) {
for (j = 0; j<m1_c; j++) {
scanf("%d", &b[i][j]);
}
}
To avoid this sort of error, you could use a better naming convention for your variables; and also consider using a struct which holds each pointer plus its dimension variables. Then you can have a function that zeroes any matrix and you only need to pass it a pointer to one of your matrix structs.
BTW if you use calloc instead of malloc then you don't need this loop at all (although you might want to have this function anyway so that you can zero a matrix).
Also you should check for success of scanf and malloc.

There are hell lot of bugs in your code:
First
//memory for 3rd matrix
c = malloc(m1_r * sizeof(int *));
for(i=0; i < m2_r; i++) <----- error: used m2_r instead of m1_r
You assigned m1_r and loop till m2_r.
Second
//input 2nd matrix
printf("Enter the second of the first matrix.\n");
for (i=0; i<m1_r; i++) { <----- error: used m1_r instead of m2_r
for (j = 0; j<m1_c; j++) { <----- error: used m1_c instead of m2_c
scanf("%d", &b[i][j]);
}
}
You are using rows and columns of 1st matrix.
Third
//initialize result matrix to 0
for(i=0; i<m2_r; i++) <----- error: used m2_r instead of m1_r
for(j=0; j<m2_c; j++) {
c[i][j]=0;
}
You used row value of second matrix rather than the first matrix

Related

Error in calculating resultant matrix in C programming language

I am trying to write a program where I have two matrices and I multiply the two matrices and store it in a resultant matrix named "carr." For some weird reason, the matrix multiplication is not getting executed properly. Tried to find the issue for quite a while but couldn't find the error. Can anyone help? TIA for your time!
Here is the ss of the issue: https://snipboard.io/s9ifP4.jpg
#include <stdio.h>
int main()
{
int row1, column1, row2, column2,i,j,k, sum=0;
//START OF THE 1ST ARRAY//
printf("How many rows do you want for the first matrix? Ans: ");
scanf("%d", &row1);
printf("How many columns do you want for the first matrix? Ans: ");
scanf("%d", &column1);
int arr[row1][column1];
printf("Enter the elements of the first array:\n");
for(i = 0; i <row1; i++){
for(j=0; j < column1; j++){
scanf("%d", &arr[i][j]);
}
}
printf("\n----------------------------------------\n");
printf("The elements of the first array are:\n");
for(i = 0; i <row1; i++){
printf("[ ");
for(j=0; j < column1; j++){
printf("%d, ", arr[i][j]);
}
printf("]\n");
}
//END OF THE FIRST ARRAY//
printf("----------------------------------------\n");
//START OF THE 2ND ARRAY//
printf("\n**How many rows do you want for the second matrix?\n\nAlert: For matrix multiplication, the COLUMN of the 1st matrix MUST equal to the ROW of the 2nd matrix.\nAns: ");
scanf("%d", &row2);
printf("How many columns do you want for the second matrix? Ans: ");
scanf("%d", &column2);
int barr[row2][column2];
printf("Enter the elements of the second array:\n");
for(i = 0; i <row2; i++){
for(j=0; j < column2; j++){
scanf("%d", &arr[i][j]);
}
}
printf("\n----------------------------------------\n");
printf("The elements of the second array are:\n");
for(i = 0; i <row2; i++){
printf("[ ");
for(j=0; j < column2; j++){
printf("%d, ", arr[i][j]);
}
printf("]\n");
}
printf("----------------------------------------\n");
//END OF THE 2ND ARRAY//
//Everything above this part is okay. The problem starts from the Matrix multiplication part//
//MATRIX MULTIPLICATION//
//The resultant matrix where the values of the multiplied matrix is being held has row = ROW1 and column = COLUMN2.//
int carr[row1][column2];
if(column1 == row2)
{
for(i = 0; i < row1; i++){
for(j=0; j < column2; j++){
for(k=0; k < row2; k++){
sum = sum + arr[i][k] * barr[k][j];
}
carr[i][j] = sum;
sum=0;
}
}
}
else
{
printf("Matrix multiplication is not possible");
}
printf("\n----------------------------------------\n");
printf("The elements of the resultant array are:\n");
for(i = 0; i <row1; i++){
printf("[ ");
for(j=0; j < column2; j++){
printf("%d, ", carr[i][j]);
}
printf("]\n");
}
printf("----------------------------------------\n");
return 0;
}
Changing arr to barr fixes the issue. Thanks to #M Oehm for pointing out the error.

Printing matrix from an txt file in C

I have to read the number of rows and columns of a matrix from a txt file also its elements. the first row is the number of rows and columns followed by its numbers. For example this is a matrix with 2 rows and 3 columns containing 123 456 and a matrix with 3 rows and 2 columns.
2 3
1 2 3
4 5 6.
3 2
1 2
3 4
5 6
What I have to do is to read two matrix from the same text file and multiply them. I'm encountering some unknown problem.
When I write my code to test whether the matrix is populated correctly. I only get the first matrix printed and then the program stopped. Output: 1 2 3
4 5 6
Here's the part of the code. Thanks in advance.
int main(){
int **mat1,**mat2,**result;
int row1,col1,row2,col2;
int i,j,k;
FILE *file;
char fname[100];
printf("enter file name\n");
scanf("%s", &fname);
file=fopen(fname, "r");
fscanf(file, "%d %d", &row1,&col1);//row of first matrix
mat1=malloc(row1 * col1 * sizeof(int*));//create memory for first matrix
//reading data for first matrix
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
fscanf(file, "%d", &mat1[i][j]);
}
}
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
printf("%d\t",mat1[i][j]);
}
printf("\n");
}
fscanf(file,"%d %d", &row2, &col2);//row of second matrix
mat2=malloc(row2 * col2 * sizeof(int*));//create memory for second matrix
//reading data for second matrix
for(i=0; i<row2; i++)
{
for(j=0; j<col2; j++)
{
fscanf(file,"%d",&mat2[i][j]);
}
}
for(i=0; i<row2; i++) //check mat2
{
for(j=0; j<col2; j++)
{
printf("%d\t",mat2[i][j]);
}
printf("\n");
}
I think I fixed the problem, but I had to do quite a bit of debugging due to lots of segfaults, so I'll put the answer to the original question at the top and defer all the things I had to debug to the bottom.
fscanf(file, "%*[.]"); //this is to read the period in the file
fscanf(file,"%d %d", &row2, &col2);//row of second matrix
mat2=malloc(row2 * col2 * sizeof(int*));//create memory for second matrix
By adding that one line of code, it started working for me, but it only started working due to the debugging below.
Since the number of calls to malloc did not represent the number of nested ararys that were indexed, I had to change the declaration of the matrices, the way they were populated, and they way they are referenced.
int *mat1,*mat2;
This declaration is to make the next edits work.
//reading data for first matrix
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
fscanf(file, "%d", &(mat1[i*col1 + j]));
}
}
for(i=0; i<row1; i++)
{
for(j=0; j<col1; j++)
{
printf("%d\t",mat1[i*col1 + j]);
}
printf("\n");
}
And of course, for the second matrix;
//reading data for second matrix
for(i=0; i<row2; i++)
{
for(j=0; j<col2; j++)
{
fscanf(file,"%d",&(mat2[i*col2 + j]));
}
}
for(i=0; i<row2; i++) //check mat2
{
for(j=0; j<col2; j++)
{
printf("%d\t",(mat2[i*col2 + j]));
}
printf("\n");
}
Please keep in mind that if you are going to be referencing an array inside of an an array, then you need to malloc space for another array in each slot of the original array. I chose the unintuitive approach to matrix arithmetic, but the code can be augmented to easily allow for double array indexing to be used.
You have some problem with allocating a 2D arrays:
For example:
mat1=malloc(row1 * col1 * sizeof(int*));//create memory for first matrix
it should be
mat1=(int**)malloc(row1 * sizeof(int*));//create memory for first matrix
Then should allocate each row in mat1 in for loop with before scanf each cell in a matrix
for (i = 0; i < row1; i++)
{
mat1[i] = malloc(col1 * sizeof(int));
for (j = 0; j < col1; j++)
{
fscanf(file, "%d", &mat1[i][j]);
}
}
Then, do similar stuff for mat2
Here is my solution that based on original problem:
#include <stdio.h>
#include <stdlib.h>
int main() {
int **mat1, **mat2, **result;
int row1, col1, row2, col2;
int i, j, k;
FILE *file;
char fname[100];
printf("enter file name\n");
scanf("%s", &fname);
file = fopen(fname, "r");
fscanf(file, "%d %d", &row1, &col1);//row of first matrix
mat1 = (int **)malloc(row1 * sizeof(int*));//create memory for first matrix
//reading data for first matrix
for (i = 0; i < row1; i++)
{
mat1[i] = malloc(col1 * sizeof(int));
for (j = 0; j < col1; j++)
{
fscanf(file, "%d", &mat1[i][j]);
}
}
for (i = 0; i < row1; i++)
{
for (j = 0; j < col1; j++)
{
printf("%d\t", mat1[i][j]);
}
printf("\n");
}
fscanf(file, "%d %d", &row2, &col2);//row of second matrix
mat2 = (int **)malloc(row2 * sizeof(int*));//create memory for second matrix
//reading data for second matrix
for (i = 0; i < row2; i++)
{
mat2[i] = malloc(col2 * sizeof(int));
for (j = 0; j < col2; j++)
{
fscanf(file, "%d", &mat2[i][j]);
}
}
for (i = 0; i < row2; i++) //check mat2
{
for (j = 0; j < col2; j++)
{
printf("%d\t", mat2[i][j]);
}
printf("\n");
}
fclose(file);
return 0;
}

Dynamic matrix initialization with scanf()

I need to make some functions for 2-dimensional arrays (a.k.a. matrixes) and the problem just starts with the first one.
I allocated the matrix in the heap memory using malloc() and then I tried to make a function that initializes the matrixes using a for loop of scanf()s, but after 3 times it takes the input, the program crashes.
Here is the code I made
void initMatrix(int **mat,int row,int col)
{
for(int i=0;i<row;i++){
printf("\n");
for(int j=0;j<col;i++){
printf("Cell (%d,%d): ",i,j);
scanf("%d",&mat[i][j]);
}
}
}
int main()
{
int r,c;
printf("Number of rows: ");
scanf("%d",&r);
printf("Number of columns: ");
scanf("%d",&c);
int **arr = (int **)malloc(sizeof(int*) * r);
for(int i=0;i<r;i++)
arr[i]=(int*)malloc(sizeof(int) * c);
// int count=0;
// for (int i = 0; i < r; i++)
// for (int j = 0; j < c; j++)
// arr[i][j] = ++count;
for (int i = 0; i < r; i++){
printf("\n");
for (int j = 0; j < c; j++)
printf("%d ", arr[i][j]);
}
initMatrix(arr,r,c);
printf("\n");
free(arr);
}
If I manually insert the content of the matrix, the program does work (without the initmatrix() function), I don't know why… I probably made a mistake somewhere.

Trying to multiply two large matrixes of dimension 1000*1000 causes Segmentation Fault [duplicate]

This question already has answers here:
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 4 years ago.
Trying to multiply two matrices of the dimension 1000*1000 . However, trying to do so causes Segmentation fault. what is possibly causing this and how to resolve it?
#include <stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
clock_t t;
t = clock();
long int a[1000][1000], b[1000][1000], result[1000][1000], r1=1000, c1=1000, r2=1000, c2=1000, i, j, k;
// Column of first matrix should be equal to column of second matrix and
/* while (c1 != r2)
{
printf("Error! column of first matrix not equal to row of second.\n\n");
printf("Enter rows and column for first matrix: ");
scanf("%d %d", &r1, &c1);
printf("Enter rows and column for second matrix: ");
scanf("%d %d",&r2, &c2);
}
*/
// Storing elements of first matrix.
printf("\nEnter elements of matrix 1:\n");
for(i=0; i<r1; ++i)
for(j=0; j<c1; ++j)
{
a[i][j]=rand()%20;
}
// Storing elements of second matrix.
printf("\nEnter elements of matrix 2:\n");
for(i=0; i<r2; ++i)
for(j=0; j<c2; ++j)
{
b[i][j]=rand()%20;
}
// Initializing all elements of result matrix to 0
for(i=0; i<r1; ++i)
for(j=0; j<c2; ++j)
{
result[i][j] = 0;
}
// Multiplying matrices a and b and
// storing result in result matrix
for(i=0; i<r1; ++i)
for(j=0; j<c2; ++j)
for(k=0; k<c1; ++k)
{
result[i][j]+=a[i][k]*b[k][j];
}
// Displaying the result
printf("\nOutput Matrix:\n");
for(i=0; i<r1; ++i)
for(j=0; j<c2; ++j)
{
printf("%ld ", result[i][j]);
if(j == c2-1)
printf("\n\n");
}
t = clock() - t;
double time_taken = ((double)t)/CLOCKS_PER_SEC; // in seconds
printf("\n \nfunction took %f seconds to execute \n", time_taken);
return 0;
}
You need to use dynamic memory allocation in the case of there large memory allocations. Stack memory cannot handle these large memory requirements.
You can solve this using Dynamic memory allocation. Try :-
int (*a)[r1][c1] = malloc(sizeof *a);
int (*b)[r2][c2] = malloc(sizeof *b);
int (*result)[r1][c2] = malloc(sizeof *result);
And access elements using :-
(*result)[i][j] ;
(*a)[i][k] ;
(*b)[k][j] ;
Try this code :-
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
clock_t t;
t = clock();
int r1 = 1000, c1 = 1000, r2 = 1000, c2 = 1000, i, j, k;
// Dynamic allocation.
int(*a)[r1][c1] = malloc(sizeof *a);
int(*b)[r2][c2] = malloc(sizeof *b);
int(*result)[r1][c2] = malloc(sizeof *result);
// Storing elements of first matrix.
printf("\nEnter elements of matrix 1:\n");
for (i = 0; i < r1; ++i)
{
for (j = 0; j < c1; ++j)
{
(*a)[i][j] = rand() % 20;
}
}
// Storing elements of second matrix.
printf("\nEnter elements of matrix 2:\n");
for (i = 0; i < r2; ++i)
{
for (j = 0; j < c2; ++j)
{
(*b)[i][j] = rand() % 20;
}
}
// Initializing all elements of result matrix to 0
for (i = 0; i < r1; ++i)
{
for (j = 0; j < c2; ++j)
{
(*result)[i][j] = 0;
}
}
// Multiplying matrices a and b and
// storing result in result matrix
for (i = 0; i < r1; ++i)
for (j = 0; j < c2; ++j)
for (k = 0; k < c1; ++k)
{
(*result)[i][j] += (*a)[i][k] * (*b)[k][j];
}
// Displaying the result
printf("\nOutput Matrix:\n");
for (i = 0; i < r1; ++i)
for (j = 0; j < c2; ++j)
{
printf("%d ", (*result)[i][j]);
if (j == c2 - 1)
printf("\n\n");
}
t = clock() - t;
double time_taken = ((double)t) / CLOCKS_PER_SEC; // in seconds
printf("\n \nfunction took %f seconds to execute \n", time_taken);
free(a);
free(b);
free(result);
return 0;
}
Output :-
.......................................................................
91717 92211 96529 90328 89167 88774 90433 88320 93834 89054 92225 92226 89919 88005 90772 90436 89091 92446 88477 94143 95777 88805 88487 89082 92528 88899 93436 90423 88637 90254 91569 87516 89079 91309 93554 86422 90069 91096 86981 95437 92805 88638 89828 88568 89607 88025 91700 88144 90401 91147 88284 92998 90959 85520 92640 92247 95616 90006 87248 89726 91751 90077 90543 91489 92399 90828 89026 92866 91548 87131 88450 93247 87748 90734 90228 91972 93300 92444 91592 85842 91167 89554 91144 90536 91256 89646 92815 91476 91863 94836 95462 87122 91735 96059 91312 90480 93306
function took 6.060788 seconds to execute
Note : Full output can't be included since too large.
Don't forget to free allocated memory.
First of all do not allocate such a huge amounts of memory as the local function variables. Their storage location (usually the stack) is relatively small comparing to the size of the heap You just run out of the automatic variables storage.. Instead allocate it dynamically
int *a = malloc(r1 * c1 * sizeof(*a));
int *b = malloc(r2 * c2 * sizeof(*b));
int *result = malloc(r2 * c2 * sizeof(*result));
printf("\nEnter elements of matrix 1:\n");
for(i=0; i<r1; ++i)
for(j=0; j<c1; ++j)
{
a[i * c1 + j]=rand()%20;
}
....
You can have another allocation strategy to have more natural indexing.

C how to insert a value in to a two dimenssion array

I have the following code which is driving me nuts. I am trying to input values into a 2-dimensional array.
I do not really know how I can insert a value in to specific location in the array. For example I want to enter the values in a pyramid fashion. I should be able to add one more value in each level.
a[0][0] ===> 1
a[1][0] & [1][1] &[1][2] ===> 2 3
a[2][0] & [2][0] & [2][2] ===> 4 5 6 etc.
I also want to be able to store the greatest integer In each level so that I can sum all the large integers in each level.
So far with the following code, I am unable to figure out how to insert the value and I also cannot sum the greatest values in each level.
for(i = 0; i < 2; i++){
for(j = 0; j <= 4; j++){
printf("Enter the values in to the array");
scanf("%d",&arr[i][j]);
}
}
for(i = 0; i < 2; i++){
for(j = 0; j <= 4; j++){
if(arr[i][j] > arr[i][j+1]){
holder = arr[i][j];
}else{
holder = arr[i][j+1];
}
}
sum = sum+holder;
}
printf("%d\n\n",sum);
To enter the values in a pyramid fashion & calculate the sum of the largest numbers of each row, try the code below:
int arr[5][10];
int i,j;
int holder=0;
int sum = 0;
for (i=0;i<5;i++)
{
for(j=0; j<=i;j++)
{
printf("Enter your input: \n");
scanf("%d", &arr[i][j]);
if(arr[i][j] > holder)
{
holder = arr[i][j];
}
}
printf("Largest Value in Row %d is %d\n", i, holder);
sum = sum + holder;
holder = 0;
}
printf(" Sum = %d\n", sum);
Try the code below for dynamically deciding the array size and assigning the values:-
int **arr;
int *greatest_each_lavel;
int n, i, j, temp;
printf ("enter the level.\n");
scanf ("%d", &n);
if (n<1)
{
printf ("Wrong input.\n");
exit (1);
}
greatest_each_level = (int *) malloc (n * sizeof (int));
arr = (int **) malloc (n * sizeof (int *));
for (i=1; i<=n; i++)
{
arr[i] = (int *) malloc (i * sizeof (int));
}
// Populate the array members.
for (i=0; i<n; i++)
{
temp = 0;
for (j=0; j<=i; j++)
{
printf ("Enter the number ");
scanf ("%d", &arr[i][j]);
if (arr[i][j] > k)
{
temp = arr[i][j];
}
}
greatest_each_level[i] = temp;
}
// To get the sum of greatest number at each level
int sum = 0;
for (i = 0; i < n; i++)
sum = sum + greatest_each_level[i];
printf ("Sum is : %d\n", sum);
// When all task are done, dont forget to free the memory.
for (i=0; i<n; i++)
{
free (arr[i]);
}
free (arr);
free (greatest_each_level);
greatest_each_level = NULL;
arr = NULL;

Resources