c - 分配故障分配给2d阵列

时间:2015-11-01 21:43:14

标签: c dynamic multidimensional-array segmentation-fault allocation

我试图获取bmp文件并制作灰度副本。我正在学习动态分配,我必须动态分配一个2D数组,我将bmp文件导入并操作它,因此它可以处理各种图像大小。但接近尾声(我标记在哪里)我得到了一个Seg Fault,我不明白为什么。如果我不动态分配"像素"。

,一切都很有效
#include <stdio.h>
#include <stdlib.h>     

int main(void) {

    const int HEADER_SIZE = 54;

    FILE *infile = fopen("test1.bmp", "rb"); 
    FILE *outfile1 = fopen("copy1.bmp", "wb");

    int i, width, height, r, c, bmpsize;
    char header[HEADER_SIZE], filename[32];
    char **pixels;                                //initialize pixels here

    puts("Enter the filename: ");

    i = -1;
    while(filename[i] != '\n')
    {
         i++;
         scanf("%c", &filename[i]);
    }
    filename[i] = '.';
    filename[i+1] = 'b';
    filename[i+2] = 'm';
    filename[i+3] = 'p';
    filename[i+4] = '\0';

    i = -1;
    while(filename[i] != '\0')
    {
         i++;
         printf("%c", filename[i]);
    }

    infile = fopen(filename, "rb");

    puts("Enter the height and width (in pixels): ");
    scanf("%d%d", &height, &width);

    bmpsize = 3 * width * height;

    pixels =  malloc(height * sizeof(char*));            //DA part 1

    for(i = 0; i < height; i++)
    {
        pixels[i] = malloc((width * 3) * sizeof(char));  //DA part 2
    }

    fread(header, 1 , HEADER_SIZE, infile);
    fread(pixels, 1 , bmpsize, infile);

    for( r = 0; r < height; r++) {
         for ( c = 0; c < width*3; c += 3) {
             int avg= 0;
             puts("THIS PUTS PRINTS: THE NEXT LINE IS MY PROBLEM");
             avg = ((int) pixels[r][c] + (int) pixels[r][c+1] + (int) pixels[r][c+2]) / 3;//This is my problem line, why?
             puts("THIS PUTS DOESN'T PRINT. ERROR: SEG. FAULT(core dumped)");
             pixels[r][c] = (char) avg;
             pixels[r][c+1] = (char) avg;
             pixels[r][c+2] = (char) avg;
         }
    }

    puts("Done. Check the generated images.");

    fwrite(header, sizeof(char)  , HEADER_SIZE,  outfile1);
    fwrite(pixels, sizeof(char)  , bmpsize,  outfile1);

    fclose(infile);
    fclose(outfile1);
    return 0;
}

2 个答案:

答案 0 :(得分:1)

我认为问题在于您的fread调用以及如何为文件内容设置输入缓冲区

pixels =  malloc(height * sizeof(char*));            //DA part 1

for(i = 0; i < height; i++)
{
    pixels[i] = malloc((width * 3) * sizeof(char));  //DA part 2
}

fread(pixels, 1 , bmpsize, infile);

您已分配总计的内存为bmpsize字节,但pixels的长度仅为height字节 - 但您将其传递给{ {1}}好像它是fread字节长度的缓冲区。 bmpsize中的每个元素都是pixels - 每个元素的地址都是动态分配的数组块,但这并不意味着您可以将char*数组视为连续的内存块。

因此,在循环中动态分配的这些数组不会被初始化,这可能会导致在循环中稍后读取它们时导致段错误(读取未初始化的变量是未定义的行为)。

这可能解释了为什么你的代码在使用非动态分配的2D数组时有效 - 因为这样的2D数组在内存中是连续的。

答案 1 :(得分:0)

c的答案几乎是正确的,因为您正在从您已分配的区域外部访问数据,但内部循环中3*width-1的最后一个索引不是{{ 1}}也不是3*width-3,但它实际上是width*3

您应该将内循环调整为:

for ( c = 0; c < width*3-3; c += 3)

这种方式c将持续到width*3-3,然后您可以执行cc+1c+2,然后您将访问这些行的最后字节与c+2