【问题标题】:C 2d array ClassC 二维数组类
【发布时间】:2021-07-18 20:55:46
【问题描述】:

我必须创建一个新的img_t,其中包含初始大小的行和列。如果成功(内存分配成功),则返回一个指向新分配的img_t的指针。

我无法初始化行和列。

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;

//something is wrong in this constructor*******
img_t* img_create(unsigned int rows, unsigned int cols){
        img_t **arr = malloc(rows * sizeof(img_t*));
        for(int i = 0; i < rows; i++){
           arr[i] = malloc(cols * sizeof(img_t));
           arr[i]->rows = rows;
      
           return arr[i]; 
        }
        return 0; 
    }

// 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_result_t test_result = IMG_OK;

    // test task 01 & 02
    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\n");
    printf("Printing test_im\n");
    print_img(test_im);
}

程序输出:

test_im
Printing test_im
Printing img of row length 10 and col length 0:

【问题讨论】:

  • return arr[i]; 你明白return 会立即终止函数吗?这意味着for 循环只运行一次。此外,很明显,您要为像素字段而不是整个 img_t 创建一个二维数组。

标签: c multidimensional-array heap-memory


【解决方案1】:

您的类型和尺寸无处不在。您正在构造一个由 img_t * 大小的对象组成的数组,长度为行,然后在循环的第一次迭代中立即返回(在为您的结构分配过多内存之后)。

您没有设置colspixels,并且正在泄漏arr 持有的内存。

img_create 应该返回一个指向img_t 结构的指针。此结构包含uint8_t 的二维数组和维度。

img_t *img_create(unsigned int rows, unsigned int cols) {
    img_t *img = malloc(sizeof *img);

    img->rows = rows;
    img->cols = cols;
    img->pixels = malloc(rows * sizeof *img->pixels);

    for (unsigned int i = 0; i < rows; i++)
        img->pixels[i] = calloc(cols, sizeof *img->pixels[i]);

    return img;
}

此示例使用calloc,将每一行初始化为包含零。 *alloc 函数可能会返回 NULL - 您需要考虑在该事件中该怎么做。

free这个结构,反转步骤。

另请注意,unsigned int 的正确 printf 说明符是 "%u",而对于 uint8_t,它在宏 PRIu8 中定义。

一个工作示例:

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct {
    uint8_t **pixels;
    unsigned int rows;
    unsigned int cols;
} img_t;

img_t *img_create(unsigned int rows, unsigned int cols) {
    img_t *img = malloc(sizeof *img);

    img->rows = rows;
    img->cols = cols;
    img->pixels = malloc(rows * sizeof *img->pixels);

    for (unsigned int i = 0; i < rows; i++)
        img->pixels[i] = calloc(cols, sizeof *img->pixels[i]);

    return img;
}

void print_img(img_t *img) {
    if (img == NULL) {
        fprintf(stderr, "Invalid img (null).\n");
        return;
    }

    printf("Printing img of row length %u and col length %u:\n",
            img->rows, img->cols);

    for (unsigned int i = 0; i < img->rows; i++) {
        for (unsigned int j = 0; j < img->cols; j++)
            printf("%" PRIu8 " ", img->pixels[i][j]);

        printf("\n");
    }
}

void img_destroy(img_t *img) {
    for (unsigned int i = 0; i < img->rows; i++)
        free(img->pixels[i]);
    free(img->pixels);
    free(img);
}

int main(void) {
    img_t *i = img_create(10, 10);

    print_img(i);

    img_destroy(i);
}

【讨论】:

  • 您好,非常感谢您说得这么清楚。另一件事,如果我不想将行初始化为包含零,我该怎么办,只想分配内存?
  • @robin110 只需改用malloc,但要知道访问未初始化的数据是Undefined Behavior。您必须在使用前的某个时间点初始化此数据。我使用了calloc,以便可以立即测试您的print_img 函数,并且您可以看到一些结果(0 的行和行)。
  • @robin110 我用更完整的例子更新了答案。请考虑accepting the answer if it best solves your problem.
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-23
  • 2015-05-03
相关资源
最近更新 更多