You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 23:18:02