Segmentation Fault in Passing String Literal as Argument in C

2609 views c
7

I was trying to write a program to perform matrix multiplication using OpenMP in C. I am facing a segmentation fault error whenever I am trying to pass a string literal as an argument to a function.

#include<stdio.h>
#include<time.h>
#include<omp.h>

struct matrix{
    int r;
    int c;
    int mat[1000][1000];
};

void read_matrix(char* fname, struct matrix* m){
    FILE *fp;
    fp = fopen(fname,"r");

    fscanf(fp, "%d %d",&m->r,&m->c);
    for(int i=0;i<m->r;i++){
        for(int j=0;j<m->c;j++){
            fscanf(fp, "%d", &m->mat[i][j]);
        }
    }
    fclose(fp);
}

void write_matrix(char* fname, struct matrix m){
    FILE *fp;
    fp = fopen(fname,"w");
    fprintf(fp,"%d %d\n",m.r,m.c);
    for(int i=0;i<m.r;i++){
        for(int j=0;j<m.c;j++){
            fprintf(fp,"%d\n",m.mat[i][j]);
        }
    }
    fclose(fp);
}

void main(){
    struct matrix m1;
    struct matrix m2;
    struct matrix res;
    read_matrix("m1",&m1);
    read_matrix("m2",&m2);
    int r1 = m1.r;
    int c1 = m1.c;
    int c2 = m2.c;
    res.r = r1;
    res.c = c2;
    for(int i=0;i<r1;i++){
        for(int j=0;j<c2;j++){
            res.mat[i][j] = 0;
        }
    }
    #pragma omp parallel
    {
        #pragma omp for
        for(int i = 0; i < r1; i++){
            for(int j = 0; j < c2; j++){
                for(int k = 0; k < c1; k++){
                    #pragma omp atomic update
                    res.mat[i][j] += m1.mat[i][k]*m2.mat[k][j];
                }
            }
        }
    }
    write_matrix("res",res);

}

The code shows Segmentation fault (core dumped) when run. When run on GDB, it shows that Program received signal SIGSEGV, Segmentation fault. 0x0000000000400ad9 in main () at mm.c:40 40 read_matrix("m1",&m1); Before the first read_matrix() call I added a printf statement printf("check\n"); The printf call now started throwing a segmentation fault. I am assuming that passing a string literal is the cause of error. What could possibly be wrong with the code?

answered question

Did you check the return value of fopen() ?

Struct matrix has 7 megabytes on 64bit. What is the output of ulimit -s and ulimit -a on your system? Is you system 64-bit?

You are not checking if m->r and m->c are lower than 1000, any value higher than 1000 there might result in out of bounds access and segfault.

Right, are values of m->r and m->c below 1000? Can you show example input? What is the expected output? Does this happen with (struct matrix)->mat being an array of a small size, like mat[10][10]?

Looks like Afshin cracked the problem. main() reserves more stack space than there is available, as soon as you try to call any function and start pushing parameter data out of bounds of the stack the program will crash. You need to either dynamically allocate those structs, or make them global, or make them static, anything to move them out of the stack. Variables this size allocated locally won't do.

1 Answer

1

Before the first read_matrix() call I added a printf statement printf("check\n"); The printf call now started throwing a segmentation fault.

I think it may happen because you allocate struct matrix on stack. each matrix is around 4MB, so 12MB on stack. I guess it creates site (stack overflow).

Try using static variables for matrices or dynamically allocate them. It may solve your problem. And if it doesn't, never allocate 12MB of structures on stack...

posted this

Have an answer?

JD

Please login first before posting an answer.