fread需何种指针?将BMP读入RGB二维数组遇类型不兼容错误
问题分析与解决
错误核心原因
报错的关键在fread(pic[x][y],3,1,file);这一行:
pic[x][y]是RGB结构体变量,而fread的第一个参数要求是void*类型的指针(指向接收数据的内存地址)。直接传变量本身会导致类型不匹配——变量不是指针,无法被fread用来写入数据。
代码修复步骤
1. 修正fread的参数
将pic[x][y]改为&pic[x][y],传入结构体的内存地址:
fread(&pic[x][y], sizeof(RGB), 1, file);
用sizeof(RGB)替代硬编码的3更稳妥,即便结构体因内存对齐规则发生变化,也能保证读取字节数正确。
2. 修复循环边界错误
原循环for (int y=hojde-1;y>0;y--)会漏掉y=0这一行,导致少读一行像素数据,修正为:
for (int y = hojde - 1; y >= 0; y--)
3. 调整填充字节的跳过逻辑
BMP图像每行数据是4字节对齐的,需要读完每一行后跳过填充字节,而非所有行读完后统一跳转。修正后的完整read函数:
void read(RGB** pic, FILE* file, int hojde, int brede) { for (int y = hojde - 1; y >= 0; y--) { for (int x = 0; x < brede; x++) { fread(&pic[x][y], sizeof(RGB), 1, file); } // 计算并跳过当前行的填充字节,避免地址偏移错误 int padding = (4 - (brede * 3) % 4) % 4; fseek(file, padding, SEEK_CUR); } return; }
这个padding计算方式能避免当brede*3正好是4的倍数时,错误跳过4字节的问题。
fread的指针要求说明
fread的第一个参数是void*类型,意味着它可以接受任意类型的指针(C语言中所有指针都能隐式转换为void*)。你只需要传入指向要存储数据的内存区域的指针即可,比如:
- 单个变量的地址:
int num; fread(&num, sizeof(int), 1, file); - 数组名(本身就是指向首元素的指针):
int arr[10]; fread(arr, sizeof(int), 10, file);
内容的提问来源于stack exchange,提问作者Jens Nielsen
相关产品推荐
相关产品推荐

