C语言img_set函数无法为二维动态像素数组赋值问题排查
问题原因及修复方案
核心错误点
img_set函数错误修改图片结构体原有宽高:函数内执行im->rows = row; im->cols = col;直接覆盖了图片创建时的合法宽高,破坏了结构体原有数据- 下标校验逻辑完全错误:C语言数组下标从0开始,合法行范围是
[0, im->rows - 1],合法列范围是[0, im->cols - 1]。你的代码判断row <= 0直接把合法的0下标判定为非法,这就是测试时i=0就报错的直接原因 - 返回值不符合要求:函数声明返回
img_result_t类型的状态码,你错误返回了传入的val参数,校验通过后应该返回IMG_OK img_create函数存在隐藏问题:像素行分配时大小计算错误,应该按uint8_t大小分配而非img_t;行分配失败时释放逻辑写错,会导致内存泄漏甚至崩溃
修复后完整代码
#include <stdio.h> #include <assert.h> #include <stdlib.h> #include <string.h> #include <stdint.h> typedef struct { uint8_t** pixels; unsigned int rows; unsigned int cols; } img_t; /// 状态码返回类型 typedef enum { IMG_OK, IMG_BADINPUT, IMG_BADARRAY, IMG_BADCOL, IMG_BADROW, IMG_NOTFOUND } img_result_t; img_t *img_create(unsigned int rows, unsigned int cols){ img_t* arr = malloc(sizeof(img_t)); if(arr == NULL) return arr; arr->rows = rows; arr->cols = cols; arr->pixels = malloc(rows * sizeof(*arr->pixels)); if(arr->pixels == NULL){ free(arr); return NULL; } for(unsigned int i = 0; i<arr->rows; i++){ // 修复:按uint8_t大小分配像素内存 arr->pixels[i] = malloc(cols*sizeof(uint8_t)); if(arr->pixels[i] == NULL){ // 修复:释放已经分配成功的前i行 for(int j= 0; j < i; j++){ free(arr->pixels[j]); } free(arr->pixels); free(arr); return NULL; } } return arr; } void img_destroy(img_t* im){ if(im != NULL){ for(unsigned int i = 0; i < im->rows; i++){ free(im->pixels[i]); } free(im->pixels); free(im); } } img_result_t img_set(img_t* im, unsigned int row, unsigned int col, int val){ // 校验图片指针合法性 if(im == NULL) return IMG_BADARRAY; // 修复:不再修改原有宽高,校验下标是否越界 if(row >= im->rows){ return IMG_BADROW; } if(col >= im->cols){ return IMG_BADCOL; } im->pixels[row][col] = (uint8_t)val; // 修复:返回正确状态码 return IMG_OK; } // 辅助函数:打印图片内容 void print_img(img_t* im) { if (im == NULL) { printf("Invalid img (null).\n"); return; } printf("Printing img of row length %d and col length %d:\n", im->rows, im->cols); for (unsigned int i=0; i<im->rows; i++) { for (unsigned int j=0; j<im->cols; j++) { printf("%d ", im->pixels[i][j]); } printf("\n"); } printf("\n"); } int main() { // 测试变量 img_t* test_im = NULL; printf("Creating test_im by calling 'img_create(10, 10)'\n"); test_im = img_create(10, 10); if (test_im == NULL) { printf("test_im == NULL\n"); return 1; } printf("test_im created successfully.\n\n"); printf("Testing img_set.\n"); for (unsigned int i=0; i<test_im->rows; i++) { for (unsigned int j=0; j<test_im->cols; j++) { if (img_set(test_im, i, j, (rand()%100)) != IMG_OK) { printf("Cannot set value at index %d\n", i); return 1; } } } printf("All values set successfully!\n"); // 可选:取消注释打印验证结果 // print_img(test_im); img_destroy(test_im); return 0; }
内容的提问来源于stack exchange,提问作者robin110
相关产品推荐
相关产品推荐

