简体   繁体   中英

Why do I get Segmentation Fault (core dumped) and no errors and warnings?

I wrote this code and after debugging for all the errors and warnings it seemed to compile, but it shows "Segmentation Fault (core dumped)" and I have no idea why it does that.

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int nrig, ncol;
    unsigned int **mat;
} matrice, *pmatrice;


void mat_alloca (pmatrice m)
{
    m->mat = malloc(m->nrig * sizeof(*m->mat));
    if (m->mat == NULL) {
        perror(__func__);
        exit(1);
    }
    m->mat[0] = calloc(m->nrig * m->ncol, sizeof(**m->mat));
    if (m->mat[0] == NULL) {
        perror(__func__);
        exit(1);
    }
}

void mat_stampa (pmatrice mat, FILE* f)
{
int i, j;
fprintf(f, "%d %d\n", mat->ncol, mat->nrig);
for (i=0; i<mat->nrig; i++){
    for(j=0; j<mat->ncol; i++){
        fprintf(f, "%2d ", mat->mat[i][j]);
    }
    fprintf(f,"\n");
}
fprintf(f, "\n");
}
void mat_leggi (pmatrice mat, FILE *f)
{
int i, j;
if (fscanf(f, "%d %d", &mat->ncol, &mat->nrig)!=2) {
    fprintf(stderr, "%s:intestazione file non corretta!\n", __func__);
    exit(1);
}
mat_alloca(mat);
for(i=0; i<mat->nrig;i++){
    for(j=0;j<mat->ncol;j++){
        fscanf(f, "%ud ", &mat->mat[i][j]);
    }
}
}
void mat_leggi_da_file(pmatrice mat, char *fn)
{
FILE *f = fopen(fn, "r");
if(!f){
    perror(fn);
    exit(1);
}
mat_leggi(mat,f);
}
void mat_stampa_su_file(pmatrice mat, char *fn)
{
FILE *f = fopen(fn, "w");
if(!f){
    perror(fn);
    exit(1);
}
mat_stampa(mat,f);
}
double media(pmatrice mat)
{
int i,j,somma=0;
int max=0,min=100;
for(i=0;i<mat->nrig;i++){
    for(j=0;j<mat->ncol;j++){
        int val = mat->mat[i][j];
        if(val>max){
            max=val;
        } else if(val<min){
            min=val;
        }
        somma += val;
    }
}
return (somma - max - min)/(double) (mat->nrig * mat->ncol -2);
}
int cmp(int *a1, int *a2, int l)
{
for(;l>0;l--,a1++,a2++){
    if(*a1>*a2) return -1;
    if(*a2>*a1) return 1;
    }
return 0;
}
void mat_bubblesort (pmatrice mat)
{
unsigned int **m = mat->mat;
int i,j,k;
for (j=mat->nrig-1;j>0; j=k) {
    k=-1;
    for(i=0;i<j;i++){
        if(cmp(m[i],m[i+1],mat->ncol)>0) {
            typeof(*m) tmp = m[i];
            m[i]=m[i+1];
            m[i+1]=tmp;
            k=i;
        }
    }
}
}






int main(int argc, char *argv[])
{
matrice mat;
if (argc>1) {
    mat_leggi_da_file(&mat, argv[1]);
    } else {
    mat_leggi_da_file(&mat, "matrice.txt");
}
mat_stampa(&mat,stdout);
printf("\n il valore medio e' %f\n", media(&mat));
mat_bubblesort(&mat);
if (argc>2){
    mat_stampa_su_file(&mat, argv[2]);
} else {
    mat_stampa(&mat, stdout);
}
return 0;
}

First issue, you are allocating 1 big buffer for the mat buffer, however, you are accessing it like a 2d array(row x col matrix). Fix the allocation try this:

void mat_alloca (pmatrice m)
{
    m->mat = malloc(m->nrig * sizeof(*m->mat));
    if (m->mat == NULL) {
        perror(__func__);
        exit(1);
    }
// problem here:    m->mat[0] = calloc(m->nrig * m->ncol, sizeof(**m->mat));    
    int r;
    for (r = 0; r < m->nrig; r++) {
        m->mat[r] = malloc(m->ncol * sizeof(int));
        if (m->mat[r] == NULL) {
            perror(__func__);
            exit(1);
        }
    }
}

Another issue is this typo in mat_stampa function, array index out of bound caused the segfault:

void mat_stampa (pmatrice mat, FILE* f)
{
    int i, j;
    fprintf(f, "%d %d\n", mat->ncol, mat->nrig);
    for (i=0; i<mat->nrig; i++){

        for(j=0; j<mat->ncol; i++){ // <=== here, should be j++ !!!

            fprintf(f, "%2d ", mat->mat[i][j]);
        }
        fprintf(f,"\n");
    }
    fprintf(f, "\n");
}

"Segmentation fault" means that you tried to access memory that you do not have access to.

There are four common mistakes that lead to segmentation faults: dereferencing NULL, dereferencing an uninitialized pointer, dereferencing a pointer that has been freed (or deleted, in C++) or that has gone out of scope (in the case of arrays declared in functions), and writing off the end of an array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM