[英]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
字节缓冲区的长度一样。 以pixels
为pixels
每个元素都是一个char*
-每个元素的地址是动态分配的数组块,但这并不意味着您可以将pixels
数组视为连续的内存块。
因此,在循环中动态分配的这些数组不会被初始化,当您稍后在循环中从数组中读取时,可能会导致段错误(读取未初始化的变量是未定义的行为)。
这可能可以解释为什么在使用非动态分配的2D数组时代码可以工作的原因-因为这样的2D数组在内存中是连续的。
mathematician1975
的答案几乎是正确的,因为您正在从分配的区域之外访问数据,但是内部循环中c
的最后一个索引不是3*width-1
或3*width-3
,但实际上width*3
。
您应该将内部循环调整为:
for ( c = 0; c < width*3-3; c += 3)
这样, c
会一直到width*3-3
,然后您可以执行c
, c+1
和c+2
并且您将使用c+2
访问行的最后一个字节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.