c - 为什么会出现段错误(核心已转储)但没有错误和警告?

标签 c

我编写了这段代码,在调试了所有错误和警告之后,它似乎可以编译,但它显示“Segmentation Fault (core dumped)”,我不知道为什么会这样。

#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;
}

最佳答案

第一个问题,您正在为 mat 缓冲区分配 1 个大缓冲区,但是,您正在像二维数组(行 x 列矩阵)一样访问它。修复分配试试这个:

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);
        }
    }
}

另一个问题是 mat_stampa 函数中的错字,数组索引越界导致了段错误:

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");
}

关于c - 为什么会出现段错误(核心已转储)但没有错误和警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37916441/

相关文章:

iOS + C : the use of __attribute__ ((__constructor__)) in static framework

c fscanf 存储字符串

c - 当变量超出范围时会发生什么?

将罗马数字转换为十进制数字

c - "initializer element is not constant"在 C99 的静态结构上使用指定的初始值设定项

c++ - 如何加快 float 到整数的转换?

c - C 的污点分析

c - 如何捕获tcp/ip数据包

交叉编译到嵌入式系统

c - 如何从汇编调用 C 函数