将值设置为 2d 动态数组数组 C
Posted
技术标签:
【中文标题】将值设置为 2d 动态数组数组 C【英文标题】:Setting value to a 2d dynamic array array C 【发布时间】:2021-10-04 18:08:03 【问题描述】:我必须确保 row 和 col 有效,我必须将 im->pixels[row][col]
的值设置为 val
并返回 IMG_OK
。
否则,数组将不被修改并返回。我知道问题出在img_result_t img_set()
,但我无法弄清楚。
我无法将 val 设置为我的数组。在运行main()
时,我得到的输出是,
Creating test_im by calling 'img_create(10, 10)'
test_im created successfully.
Testing img_set.
Cannot set value at index 0
代码:
#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;
/// A type for returning status codes
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++)
arr->pixels[i] = malloc(cols*sizeof(img_t));
if(arr->pixels[i] == NULL)
for(int j= 0; j < i; j++)
free(arr->pixels[i]);
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;
im->rows = row;
im->cols = col;
unsigned int empty = 0;
if(row <= empty)
return IMG_BADROW;
if(col <= empty)
return IMG_BADCOL;
im->pixels[row][col] = val;
return val;
// helper function that prints the content of the img
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()
// test variables to hold values returned by the functions
img_t* test_im = NULL;
img_t* null_im = NULL;
img_t* test2_im = NULL;
img_result_t test_result = IMG_OK;
int val;
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; //exit with a non-zero value
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; //exit with a non-zero value
【问题讨论】:
进行基本调试。img_set
中的哪个条件失败?使用调试器逐步执行代码。 if(row <= empty)
和 if(col <= empty)
问问你自己 row
和 col
的值是什么,你用什么来调用函数,为什么会触发这些错误条件?您可以通过任何基本的调试量轻松找到它。 How to debug small programs
您在img_set()
的末尾有return val;
,但您应该返回IMG_OK
。在您知道一切正常之前,您不应该更改任何内容,但是您从该位置设置了im->rows
和im->cols
。这可能意味着当您设置row = 0
和col = 0
像素时,您的图像会缩小。
当您检查img_set(test_im, i, j, (rand()%100)) != IMG_OK
时,该函数也会执行return val;
我认为最后的评论是一个答案,可能是答案。 @kaylum 如果您想回答并希望我删除我的,请告诉我。
【参考方案1】:
您的 img_set
函数有 4 个错误。
您覆盖了行和列的img_t
配置
您对下边界的检查是错误的
不检查上限
存储值时返回类型错误。
见 cmets。
img_result_t img_set(img_t* im, unsigned int row, unsigned int col, int val)
if(im == NULL) return IMG_BADARRAY;
im->rows = row; <--- Changing im->rows and cols are wrong.
im->cols = col; <--- Once im is created you never want to change them
unsigned int empty = 0; <--- why ? zero is always lower boundary
if(row <= empty) <--- This makes index zero invalid
return IMG_BADROW;
if(col <= empty) <--- This makes index zero invalid
return IMG_BADCOL;
// Here should check for upper boundary
im->pixels[row][col] = val;
return val; <-------- Wrong return type
试试看:
img_result_t img_set(img_t* im, unsigned int row, unsigned int col, int val)
if(im == NULL) return IMG_BADARRAY;
if(row < 0 || row >= im->rows) return IMG_BADROW;
if(col < 0 || col >= im->cols) return IMG_BADCOL;
im->pixels[row][col] = val;
return IMG_OK;
另外你在创建函数中有一个错误:
arr->pixels[i] = malloc(cols*sizeof(img_t));
^^^^^
wrong type
那我想知道为什么当你真正想要存储uint8_t
时你的set-function 将值设为int
。这不违法,但有点奇怪。
【讨论】:
【参考方案2】:我得出了和凯勒姆一样的结论:
该函数在您检查
img_set(test_im, i, j, (rand()%100)) != IMG_OK
时执行return val;
通读您的代码,我会解释您的 API 概念,因此解决方案就是简单地更改
return val;
到
return IMG_OK;
因为这是成功情况下来自img_result_t
的预期状态返回值。
【讨论】:
以上是关于将值设置为 2d 动态数组数组 C的主要内容,如果未能解决你的问题,请参考以下文章