繁体   English   中英

c-分割故障分配给二维数组

[英]c - segmentation fault assigning to 2d array

我正在尝试获取bmp文件并进行灰度复制。 我正在学习动态分配,我必须动态分配一个2D数组,该数组将bmp文件导入其中并从中进行操作,因此它将适用于各种图片尺寸。 但是,快要结束了(我在哪里标记了),我遇到了段错误,我也不知道为什么。 如果我不动态分配“像素”,一切都会很好。

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

我认为问题出在您的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字节-但您bmpsize其传递给fread ,就好像它是bmpsize字节缓冲区的长度一样。 pixelspixels每个元素都是一个char* -每个元素的地址是动态分配的数组块,但这并不意味着您可以将pixels数组视为连续的内存块。

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

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

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

您应该将内部循环调整为:

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

这样, c会一直到width*3-3 ,然后您可以执行cc+1c+2并且您将使用c+2访问行的最后一个字节。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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