【问题标题】:Segfault in an unusual placeSegfault 在一个不寻常的地方
【发布时间】:2016-11-22 18:29:59
【问题描述】:

我正在编写一些代码来为我的班级制作 .pgm 图像,当我第一次运行它时,我遇到了段错误。我有点预料到,因为我对调用初始化为 NULL 的结构的成员是出了名的糟糕。但是当我将调试语句放入(只是带有数字的 printf 函数)时,它给了我一个超出预期的段错误。

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

typedef struct pgm {
    int rows;
    int cols;
    int **pixels;
} pgmPic; 

void dataCreate(pgmPic *);
void trailCreate(pgmPic *);
pgmPic *blaze(pgmPic *, char*);

int main(int argc, char** argv){
    printf("Hi\n");
    if(argc != 3){
        printf("Improper use of arguments.\n");
        return 0;
    }
    int row, col;
    printf("point 0");
    FILE *data = fopen(argv[1], "r");
    printf("point 1");
    fscanf(data, "%d\n%d\n", &row, &col);
    printf("point 2");
    pgmPic *myPic = (pgmPic *) malloc(sizeof(pgmPic));
    myPic->pixels = (int**) malloc(sizeof(int)* myPic->rows);
    for(int a = 0; a < myPic->rows; a++)
        myPic->pixels[a] = (int*) malloc(sizeof(int) * myPic->cols);
    printf("point 3");
    int elev[row][col];
    for(int w = 0; w < row; w++){
        for(int v = 0; v < col; v++){
            fscanf(data, "%d", &elev[w][v]);
        }
    }
    printf("point 4");
    int min = elev[0][0];
    int max = elev[0][0];
    for(int x = 0; x < row; x++){
        for(int y = 0; y < col; y++){
            if(elev[x][y] < min)
                min = elev[x][y];
            if(elev[x][y] > max)
                max = elev[x][y];
        }
    }
    printf("point 5");
    double multiplier = (max-min)/200;
    for(int w = 0; w < row; w++){
        for(int v = 0; v < col; v++){
            elev[w][v] = elev[w][v] - min;
            elev[w][v] = elev[w][v] * multiplier;
            myPic->pixels[w][v] = 255 - elev[w][v];
        }
    }
    printf("point 6");
    myPic->rows = row;
    myPic->cols = col;
    printf("point 7");
    dataCreate(myPic);
    printf("point 8");
    myPic = blaze(myPic, argv[2]);
    printf("point 9");
    trailCreate(myPic);
    return 0;
}

void dataCreate(pgmPic *pic){
    FILE *myfile = fopen("data.pgm", "w");
    fprintf(myfile, "P2\n");
    fprintf(myfile, "%d %d\n", pic->cols, pic->rows);
    for(int i = 0; i < pic->rows; i++){
        for(int j = 0; j < pic->cols; j++){
            fprintf(myfile, "%3d ", pic->pixels[pic->rows][pic->cols]);
        }
        fprintf(myfile, "\n");
    }
    fclose(myfile);
} 

void trailCreate(pgmPic *pic){
    FILE *myfile = fopen("data-trail.pgm", "w");
    fprintf(myfile, "P2\n");
    fprintf(myfile, "%d %d\n", pic->cols, pic->rows);
    for(int i = 0; i < pic->rows; i++){
        for(int j = 0; j < pic->cols; j++){
            fprintf(myfile, "%3d ", pic->pixels[pic->rows][pic->cols]);
        }
        fprintf(myfile, "\n");
    } 
    fclose(myfile);
}

pgmPic *blaze(pgmPic *pic, char* dir){
    pgmPic *thing = pic;
    int row, col;
    if(strcmp(dir, "W-E") == 0){
        row = pic->rows / 2;
        col = 0;
        while(col < pic->cols){
            thing->pixels[row][col] = 0;
            col++;
            if(thing->pixels[row-1][col] <= thing->pixels[row][col] && thing->pixels[row][col] >= thing->pixels[row+1][col])
                continue;
            if(thing->pixels[row-1][col] >= thing->pixels[row][col] && thing->pixels[row-1][col] >= thing->pixels[row+1][col]){
                row--;
                continue;
            }
            if(thing->pixels[row-1][col] <= thing->pixels[row+1][col] && thing->pixels[row][col] <= thing->pixels[row+1][col]){
                row++;
                continue;
            }
        }
    }
    if(strcmp(dir, "E-W") == 0){
        row = pic->rows / 2;
        col = pic->cols - 1;
        while(col > 0){
            thing->pixels[row][col] = 0;
            col--;
            if(thing->pixels[row-1][col] <= thing->pixels[row][col] && thing->pixels[row][col] >= thing->pixels[row+1][col])
                continue;
            if(thing->pixels[row-1][col] <= thing->pixels[row+1][col] && thing->pixels[row][col] <= thing->pixels[row+1][col]){
                row++;
                continue;
            }
            if(thing->pixels[row-1][col] >= thing->pixels[row][col] && thing->pixels[row-1][col] >= thing->pixels[row+1][col]){
                row--;
                continue;
            }
        }
    }
    if(strcmp(dir, "S-N") == 0){
        col = pic->cols / 2;
        row = pic->rows - 1;
        while(col > 0){
            thing->pixels[row][col] = 0;
            row--;
            if(thing->pixels[row][col-1] <= thing->pixels[row][col] && thing->pixels[row][col] >= thing->pixels[row][col+1])
                continue;
            if(thing->pixels[row][col-1] >= thing->pixels[row][col] && thing->pixels[row][col-1] >= thing->pixels[row][col+1]){
                row--;
                continue;
            }
            if(thing->pixels[row][col-1] <= thing->pixels[row][col+1] && thing->pixels[row][col] <= thing->pixels[row][col+1]){
                row++;
                continue;
            }
        }
    }
    if(strcmp(dir, "N-S") == 0){
        col = pic->cols / 2;
        row = 0;
        while(col < pic->cols){
            thing->pixels[row][col] = 0;
            row++;
            if(thing->pixels[row][col-1] <= thing->pixels[row][col] && thing->pixels[row][col] >= thing->pixels[row][col+1])
                continue;
            if(thing->pixels[row][col-1] <= thing->pixels[row][col+1] && thing->pixels[row][col] <= thing->pixels[row][col+1]){
                col++;
                continue;
            }
            if(thing->pixels[row][col-1] >= thing->pixels[row][col] && thing->pixels[row][col-1] >= thing->pixels[row][col+1]){
                col--;
                continue;
            }
        }
    }
    return thing;
}

现在,当我运行此程序时,我预计段错误会出现在第 2 点或第 3 点之后的某个地方,但当我运行它时,我在到达第 0 点之前遇到了段错误。你知道是什么原因造成的吗?

【问题讨论】:

  • 您忘记在printfs 末尾添加换行符\n。标准输出是行缓冲的,因此来自printf 的字符会被缓冲,直到您打印换行符。
  • col++; 在一个陌生的地方。强烈建议使用 for() 循环而不是 while() 循环...
  • myPic-&gt;pixels = (int**) malloc(sizeof(int)* myPic-&gt;rows); --> myPic-&gt;pixels = (int**) malloc(sizeof(int*)* myPic-&gt;rows);
  • 你的程序会被最小的风吹倒,因为你永远不会检查来自fopenfscanfmalloc的任何关键函数返回值。
  • pgmPic *myPic = (pgmPic *) malloc(sizeof(pgmPic));之后需要myPic-&gt;rows = rowmyPic-&gt;cols = col

标签: c segmentation-fault pgm


【解决方案1】:
pgmPic *myPic = (pgmPic *) malloc(sizeof(pgmPic));
myPic->pixels = (int**) malloc(sizeof(int)* myPic->rows);

myPic指向新分配的内存,那么myPic-&gt;rows的值是多少?

我们不知道。

【讨论】:

  • 我同意这一点,但是我怀疑你没有看到在屏幕上一直打印到point2,因为你没有做printf("point2\n"); 程序正在崩溃并且输出缓冲区是没有被刷新,所以要么在每个 printf 语句中添加换行符,还可以考虑在调试时在每个 printf 之后执行fflush(stdout); ...我认为你的调试被错误了哈哈。
猜你喜欢
  • 1970-01-01
  • 2014-01-29
  • 2021-06-11
  • 2021-08-10
  • 1970-01-01
  • 2015-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多