C - matrix multiplication segmentation fault - c

I get a segmentation fault when running this code. Anyone know why? Thanks.
#include <stdio.h>
int main()
{
double **m1, **m2, **mr;
int m1_rows, m1_cols, m2_rows, m2_cols, mr_rows, mr_cols;
int i, j, k;
printf("Enter number of rows for matrix 1: ");
scanf("%d", &m1_rows);
printf("Enter number of columns for matrix 1: ");
scanf("%d", &m1_cols);
printf("Enter number of rows for matrix 2: ");
scanf("%d", &m2_rows);
printf("Enter number of columns for matrix 2: ");
scanf("%d", &m2_cols);
//allocate memory for matrix 1 m1
m1 = (double **) calloc(m1_rows, sizeof(double *));
for (i = 0; i < m1_rows; i++) {
m1[i] = (double *) calloc(m1_cols, sizeof(double));
}
//allocate memory for matrix 2 m2
m2 = (double **) calloc(m2_rows, sizeof(double *));
for (i = 0; i < m2_rows; i++) {
m2[i] = (double *) calloc(m2_cols, sizeof(double));
}
//allocate memory for sum matrix mr
mr = (double **) calloc(mr_rows, sizeof(double *));
for (i = 0; i < mr_rows; i++) {
mr[i] = (double *) calloc(mr_cols, sizeof(double));
}
//assign mr_rows and mr_cols
mr_rows = m1_rows;
mr_cols = m2_cols;
//initialize product matrix
for (i = 0; i < m1_rows; i++) {
for (j = 0; j < m2_cols; j++) {
mr[i][j] = 0;
}
}
//perform matrix multiplication
for (i = 0; i < m1_rows; i++) {
for (j = 0; j < m2_cols; j++) {
mr[i][j] = 0;
for (k = 0; k < m1_cols; k++) {
mr[i][j] += m1[i][k] * m2[k][j];
}
}
}
//print result
for (i = 0; i < mr_rows; i++) {
for (j = 0; j < mr_cols; j++) {
printf("%f\t", mr[i][j]);
}
}
//free memory m1
for (i = 0; i < m1_rows; i++); {
free(m1[i]);
}
free(m1);
//free memory m2
for (i = 0; i < m2_rows; i++); {
free(m2[i]);
}
free(m2);
//free memory mr
for (i = 0; i < mr_rows; i++); {
free(mr[i]);
}
free(mr);
return 0;
}
I ran using valgrind valgrind --tool=memcheck a.out for more info on the segmentation fault, but the result was over 30000 errors so it didn't print them out.

You are not assigning mr_rows and mr_cols. They need to be set like this:
mr_rows = m1_rows;
mr_cols = m2_cols;
This line is no good:
mr[i][j] += m1[i][k] * m2[k][j];
That will be accessing elements out of bounds, not least because k is not initialized. You need that line of code inside three nested for loops. Indeed, you may as well roll the zeroising code into this too.
for(i=0; i<m1_rows; i++){
for(j=0; j<m2_cols; j++){
mr[i][j] = 0;
for(k=0; k<m1_cols; k++){
mr[i][j] += m1[i][k]*m2[k][j];
}
}
}
Also, all your memory freeing loops are wrong. Instead of
for(i=0; i<m1_rows; i++);{
free(m1[i]);
}
free(m1);
it should read
for(i=0; i<m1_rows; i++){
free(m1[i]);
}
free(m1);
That stray semicolon was killing you.
You also need to perform a check that the number of columns in m1 equals the number of rows in m2, i.e. test that m1_cols == m2_rows.
One final point. You duplicate your code horribly here. Don't have three identical for loops to allocate a matrix and three identical for loops to deallocate. Extract those operations into helper functions which can be called from main.
That's all that I can find!

You are not assigning any values to mr_rows and mr_cols anywhere. So they will have junk values and you use them to to allocate memory by callin calloc().

Related

Keep getting segmentation fault (core dumped) in C programming and I am trying to pass a 2d array

#include <stdlib.h>
#include <stdio.h>
double **transpose(double **arr, int r, int c);
double **transpose(double **arr, int r, int c){
//will hold the transposed matrix
double **arrT;
arrT = (double **)malloc(c * sizeof(double *));
for(int i = 0; i < c; i++){
arrT[i] = (double *)malloc(r * sizeof(double));
}
//transpose the matrix
for(int i = 0; i < c; i++){
for(int j = 0; j < r; j++){
arrT[j][i] = arr[i][j];
}
}
return arrT;
}
int main(int argc, char *argv[]){
//if there is no argument
if(argc < 2){
printf("There is no argument\n");
return -1;
}
//training data
char *fname = argv[1];
//test data
char *fname2 = argv[2];
//pointer for training data
FILE *fptr;
//pointer for test data
FILE *fptr2;
//number of columns
int column;
//number of rows
int row;
//opens training data file and reads it
fptr = fopen(fname, "r");
//will scan the first line of training data
//to store column of attributes and we add
//1 more column for price
fscanf(fptr, "%d\n", &column);
//adds column for prices
column++;
printf("Number of columns: %d\n", column);
//will scan the second line of training data
//to store number of rows
fscanf(fptr, "%d\n", &row);
printf("Number of rows: %d\n", row);
//allocate array X that will hold attributes
double **X;
X = (double **)malloc(row * sizeof(double *));
//allocate array that will hold everything attributes
//and prices
double **arr;
arr = (double **)malloc(row * sizeof(double *));
//allocate array that will hold prices
double *Y;
Y = (double *)malloc(row * sizeof(double *));
for(int i = 0; i < row; i++){
X[i] = (double *)malloc(column * sizeof(double));
arr[i] = (double *)malloc(column * sizeof(double));
}
//will store the whole training data into arr
printf("This is training data: \n");
for(int i = 0; i < row; i++){
for(int j = 0; j < column; j++){
fscanf(fptr, "%lf,", &arr[i][j]);
printf("%lf\t", arr[i][j]);
}
printf("\n");
}
//copies training data for the attribute array
for(int i = 0; i < row; i++){
for(int j = 0; j < column; j++){
X[i][j] = arr[i][j];
}
}
//will set attributes first column
//to all 1's
for(int i = 0; i < row; i++){
X[i][0] = 1;
}
printf("This is attributes:\n");
for(int i = 0; i < row; i++){
for(int j = 0; j < column; j++){
printf("%lf\t", X[i][j]);
}
printf("\n");
}
//will set the first column or training
//data to the prices array
printf("This is prices: \n");
for(int i = 0; i < row; i++){
Y[i] = arr[i][0];
printf("%lf\n", Y[i]);
}
//matrix will hold transposed
double **trans;
transpose(X, row, column);
/*
printf("This is transposed of attributes\n");
for(int i = 0; i < row; i++){
for(int j = 0; j < column; j++){
printf("%lf\t", trans[i][j]);
}
printf("\n");
}
*/
return 0;
}
double **transpose(double **arr, int r, int c){
//will hold the transposed matrix
double **arrT;
arrT = (double **)malloc(c * sizeof(double *));
for(int i = 0; i < c; i++){
arrT[i] = (double *)malloc(r * sizeof(double));
}
//transpose the matrix
for(int i = 0; i < c; i++){
for(int j = 0; j < r; j++){
arrT[j][i] = arr[i][j];
}
}
return arrT;
}
Hi so i havent completed the code yet but the code should still run fine as it is. The problem is though I try to the method to transpose the matrix and when it does it says segmentation fault core dumped. If you can tell me whats wrong that would be greatly appreciated. I am trying to pass a 2d array.
The txt file it should read should be input.txt:
where 4 is the first line, and 10 is the second line.
4
10
221900,3,1,1180,1955
538000,3,2.25,2570,1951
180000,2,1,770,1933
604000,4,3,1960,1965
510000,3,2,1680,1987
1230000,4,4.5,5420,2001
257500,3,2.25,1715,1995
291850,3,1.5,1060,1963
229500,3,1,1780,1960
323000,3,2.5,1890,2003

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.

Print double pointer to array - keeps crashing

i have this small piece of code which i cant get to work.
I am kinda new and i just cant find a mistake i did. Thanks
int main (void)
{
int **array;
int i,j, m;
scanf("%d", &m);
array = malloc(sizeof(int) * (m*m));
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++)
{
scanf("%d", &array[i][j]);
}
}
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++)
{
printf("%d", array[i][j]);
}
}
return 0;
}
What you are allocating is an one dimensional array of size m*m but you are using it as if you have allocated a jagged array where each row contains m elements.
You can allocate a bit different way than what you did
array = malloc(sizeof *array * m);
if( array == NULL)
{
// error in malloc
}
for(size_t i =0; i<m; i++)
{
array[i]= malloc(sizeof *array[i] * m);
if( array[i] == NULL)
{
// error
}
}
...
for(size_t i = 0; i<m ; i++)
free(array[i]);
free(array);
Alternatively you can put all the elements in a linear manner using i and j.
int *array;
...
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++)
{
if( scanf("%d", &array[i*m+j]) != 1){
// error in getting input.
}
}
}
...
free(array);
Same goes with printf also.
Also don't forget to free the memory you have allocated dynamically after you are done working with it.

How to multiply matrix using pointers - C

I have to write a program which multiply matrix using pointers.
My program does it correctly, but there are two problems:
1) I can do only one multiplication - when I want next one there is error
2) when I input data of first and second matrix i have to put one more
char to make my program work.
What should I change in my code to solve those problems?
#include <stdio.h>
#include <stdlib.h>
while (z--) { // the number of sets
scanf ("%d %d", &n1, &m1); // first matrix n1 x m1
int **A = malloc(n1 * sizeof(int*));
for (i = 0; i < n1; i++) {
*(A+i) = malloc(m1 * sizeof(int));
}
for (i = 0; i < n1; i++) {
for (j = 0; j < m1; j++) {
scanf("%d ", (A+i*m1+j));
}
}
scanf("%d %d", &n2, &m2); // second matrix n2 x m2
int **B = malloc(n2 * sizeof(int*));
for (i = 0; i < n2; i++) {
*(B+i) = malloc(m2 * sizeof(int));
}
for (i = 0; i < n2; i++) {
for (j = 0; j < m2; j++) {
scanf("%d ", (B+i*m2+j));
}
}
if (m1 != n2) {
printf ("ERROR\n");
} else {
int **C = malloc(n1 * sizeof(int*)); //matrix with product
for (i = 0; i < n1; i++) {
*(C+i) = malloc(m2 * sizeof(int));
}
for (i=0; i<n1; i++) {
for (j=0; j<m2; j++) {
*(C+i*m2+j) = 0;
}
}
for (k = 0; k < n2; k++) {
for (i = 0; i < n1; i++) {
for (j = 0; j < m2; j++) {
C1 = 0;
A1 = *(A+i*m1+k);
B1 = *(B+k*m2+j);
C1 = (C1+A1*B1)%1000;
temp = *(C+i*m2+j);
*(C+i*m2+j) = temp+C1;
}
}
}
for (i = 0; i < n1; i++) {
for (j = 0; j < m2; j++) {
printf("%d ", *(C+i*m2 +j));
}
printf("\n");
}
for (i = 0; i < n1; i++) { // free third matrix
free(*(C+i));
}
free(C);
}
for (i = 0; i < n1; i++) { // free first matrix
free(*(A+i));
}
free(A);
for (i = 0; i < n2; i++) { // free second matrix
free(*(B+i));
}
free(B);
}
return 0;
You write to memory beyond the allocated size. This invokes undefined behavior, a good explanation for the erratic behavior you observe.
The offending code is this:
for (k=0; k<n2; k++){
for (i=0; i<n1; i++) {
for (j=0; j<m2; j++) {
C1=0;
A1=*(A+i*m1+k);
B1=*(B+k*m2+j);
C1=(C1+A1*B1)%1000;
temp=*(C+i*m2+j);
*(C+i*m2+j)=temp+C1;
}
}
}
You assume that the matrices are allocated as a single packed 2D array.
Since you allocate them as arrays of pointers to arrays of int, you cannot use this code. Use the much simpler version below:
for (k = 0; k < n2; k++){
for (i = 0; i < n1; i++) {
for (j = 0; j < m2; j++) {
C[i][j] += A[i][k] * B[k][j] % 1000;
}
}
}
It is not clear why you compute modulo 1000. If you really mean that, you should use this:
C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % 1000;
If you are not supposed to use the [] syntax, replace it with the equivalent for pointer dereferencing, not 2D array addressing. I understand what they are trying to teach you, but a diagram would be more effective than this.
*(*(C+i)+j) = (*(*(C+i)+j) + *(*(A+i)+k) * *(*(B+k)+j)) % 1000;
As you may have noticed, the [] syntax is the same for 2D arrays and arrays of pointers to arrays, but the code generated for pointer arithmetic and dereferencing is quite different.
There are other places where you need to change the indexing method, here is the corrected code:
while (z--) { // the number of sets
scanf("%d %d", &n1, &m1); // first matrix n1 x m1
int **A = malloc(n1 * sizeof(int*));
for (i = 0; i < n1; i++) {
*(A+i) = malloc(m1 * sizeof(int));
for (j = 0; j < m1; j++) {
scanf("%d ", *(A+i)+j);
}
}
scanf("%d %d", &n2, &m2); // second matrix n2 x m2
int **B = malloc(n2 * sizeof(int*));
for (i = 0; i < n2; i++) {
*(B+i) = malloc(m2 * sizeof(int));
for (j = 0; j < m2; j++) {
scanf("%d ", *(B+i)+j);
}
}
if (m1 != n2) {
printf ("ERROR\n");
} else {
int **C = malloc(n1 * sizeof(int*)); //matrix with product
for (i = 0; i < n1; i++) {
// using calloc so matrix is initialized to 0
*(C+i) = calloc(m2, sizeof(int));
}
for (k = 0; k < n2; k++) {
for (i = 0; i < n1; i++) {
for (j = 0; j < m2; j++) {
*(*(C+i)+j) = (*(*(C+i)+j) + *(*(A+i)+k) * *(*(B+k)+j)) % 1000;
}
}
}
for (i = 0; i < n1; i++) {
for (j = 0; j < m2; j++) {
printf("%d ", *(*(C+i)+j));
}
printf("\n");
}
for (i = 0; i < n1; i++) { // free third matrix
free(*(C+i));
}
free(C);
}
for (i = 0; i < n1; i++) { // free first matrix
free(*(A+i));
}
free(A);
for (i = 0; i < n2; i++) { // free second matrix
free(*(B+i));
}
free(B);
}
return 0;

segmentation fault when I take in the first value of matrix

If I run my program, and When I typed the dimensions of matrix, after I typed the first value of matrix , the console write out: Segmentation fault
For example:
4
3
Segmentation fault
Process returned 139(0x8B)
void inMatrix(int n, double **matrix)
{
int j, i;
for (i = 0; i < n; i++)
{
for (j= 0; j < n; j++)
{
scanf("%lf", &matrix[i][j]);
}
}
}
void inVector(double *vektor, int n)
{
int k;
for (k = 0; k < n; k++)
{
scanf("%lf", &vektor[k]);
}
}
int main()
{
int n;
// read dimension of matrix and value
scanf("%d", &n);
//matrix
double** matrix = (double **) calloc(n, sizeof ( double*));
//vector
double* vector = (double *) calloc(n, sizeof ( double));
// read values of matrix
inMatrix(n, matrix);
// read values of vector
inVector(vector, n);
outVector(vector, n);
printf("\n");
return 0;
}
You didn't allocate memory for the elements of the matrix, only for the pointers to the individual lines.
You need something like:
for (i = 0; i < n; i++)
matrix[i] = malloc(n * sizeof(double));
Of course, you must free stuff in the same manner when you're done with it.
for (i = 0; i < n; i++)
free(matrix[i]);
free(matrix);

Resources