C语言访问结构体存储的多维像素数组偶发非预期输出问题
问题根源
你遇到的是堆缓冲区溢出导致的未定义行为,问题出在三维像素数组的前两层内存分配逻辑,计算分配大小时用错了类型单位。
具体错误点
你的pixel_array是unsigned char***类型,三层数组的元素类型分别是:
- 第一层
pixel_array[x]:unsigned char**指针类型 - 第二层
pixel_array[x][y]:unsigned char*指针类型 - 第三层
pixel_array[x][y][z]:unsigned char字节类型
你当前的前两层分配都错误使用了sizeof(unsigned char)作为单位,仅分配了1字节/元素的空间,远小于指针类型实际需要的空间(32位系统4字节、64位系统8字节),导致写入指针数据时越界覆盖了堆上的其他内存。
赋值时打印正常是因为越界写入的内存暂时未被其他操作修改,后续堆内存被分配器元数据、其他变量覆写后,读取就会出现随机值,错误位置固定是因为越界偏移量固定,每次运行值不同是因为堆地址空间随机化。
修复方案
修改前两层malloc的大小计算逻辑即可:
// 修正第一层分配:单位为 unsigned char** 指针大小 bmp_image->pixel_array = malloc(bmp_image->width * sizeof(unsigned char**)); // 修正第二层分配:单位为 unsigned char* 指针大小 bmp_image->pixel_array[i] = malloc(bmp_image->height * sizeof(unsigned char*));
更稳妥的写法推荐
用sizeof(*变量)的方式自动匹配类型,避免后续修改类型时忘记改sizeof参数:
bmp_image->pixel_array = malloc(bmp_image->width * sizeof(*bmp_image->pixel_array)); bmp_image->pixel_array[i] = malloc(bmp_image->height * sizeof(*bmp_image->pixel_array[i]));
内容的提问来源于stack exchange,提问作者Ethan Peck
相关产品推荐
相关产品推荐

