微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用结构

如何解决使用结构

// 我必须用初始大小的行、cols 和它们的保留对应物(rows 和 reserved_rows 将相同,cols 和 reserved_cols 相同)创建一个新的 imgr_t。如果分配成功(即内存分配成功),则返回指向新分配的imgr_t的指针,如果不成功,则返回空指针。

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

/* Structure type that encapsulates image: 2D array.
 * the rows represent the indices of the main array,* the cols represent the indices of the arrays pointed to by the pointers 
 * in the elements of the main array.
*/

typedef struct { 
    uint8_t** pixels;
    unsigned int rows;
    unsigned int cols;
    unsigned int reserved_rows;
    unsigned int reserved_cols;
} imgr_t;

/***** I am thinking something is wrong here but I cannot figure out what *****/

imgr_t* imgr_create(unsigned int rows,unsigned int cols){

    imgr_t* arr;
    arr->rows = rows;
    arr->cols = cols;
    arr->reserved_rows = rows;
    arr->reserved_cols = cols;
    arr = malloc(rows*sizeof(imgr_t));
    for(int i = 0; i<arr->rows; i++){
        arr->pixels[i] = malloc(cols*sizeof(imgr_t));
    }return arr;
}

void imgr_destroy(imgr_t* im){
    if(im != NULL){
        free(im->pixels);
        free(im);
    }
}

// helper function that prints the content of the img
void print_img(imgr_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(){

  imgr_t* test_im;
  printf("Creating test_im by calling 'img_create(10,10)'\n");
  test_im = imgr_create(10,10);
  printf("test_im created successfully.\n\n");

    
  return 0;
}

/*
    Output what I am getting : Creating test_im by calling 'img_create(10,10)'
             signal: segmentation fault (core dumped)
*/

解决方法

imgr_t* imgr_create(unsigned int rows,unsigned int cols){

    imgr_t* arr;
    arr->rows = rows;
    arr->cols = cols;
    arr->reserved_rows = rows;
    arr->reserved_cols = cols;
    arr = malloc(rows*sizeof(imgr_t));
    for(int i = 0; i<arr->rows; i++){
        arr->pixels[i] = malloc(cols*sizeof(imgr_t));
    }return arr;
}

这里在初始化之前使用 arr。而且您的初始化似乎是错误的,因为您只需要分配 1 个 imgr_t 元素。像素初始化在我看来也是错误的:类型不正确,您需要使用类型 uint8_t。您还需要分配一些空间来存储您的像素:

imgr_t* imgr_create(unsigned int rows,unsigned int cols){

  imgr_t* arr = malloc(sizeof(imgr_t));
  arr->rows = rows;
  arr->cols = cols;
  arr->reserved_rows = rows;
  arr->reserved_cols = cols;
  arr->pixels = malloc(rows * sizeof(uint8_t*));

  for(int i = 0; i<arr->rows; i++){
    arr->pixels[i] = malloc(cols*sizeof(uint8_t));
  }

  return arr;
}
,

规则是调用 free 的次数与调用 malloc 的次数相同。 而 uint8_t** pixels; 不是指向二维数组的指针,而是指向数组指针的指针,因此您需要两次分配(在 free 时间也是如此)。

这里你需要:

  • 1 个分配给 imgr_t 结构
  • 1 个行指针数组分配
  • 每行 1 个分配 (*)

代码可以是:

imgr_t* imgr_create(unsigned int rows,unsigned int cols) {

    imgr_t* arr = malloc(sizeof *arr);
    if (NULL == arr) return arr;       // do not forget to test allocation!
    arr->rows = rows;
    arr->cols = cols;
    arr->reserved_rows = rows;
    arr->reserved_cols = cols;
    arr->pixels = malloc(rows * sizeof(*arr->pixels));  // allocate rows
    if (NULL == arr->pixels) {         // another allocation to test
        free(arr);
        return NULL;
    }
    for (unsigned int i = 0; i < arr->rows; i++) {
        arr->pixels[i] = malloc(cols * sizeof(uint8_t));
        if (NULL == arr->pixels[i]) { // free what was allocated so far
            for (int j = 0; j < i; j++) {
                free(arr->pixels[i]);
            }
            free(arr->pixels)
            free(arr);
            return NULL;

        }
    }return arr;
}

void imgr_destroy(imgr_t* im) {
    if (im != NULL) {
        // one free per malloc...
        for (unsigned int i = 0; i < im->rows; i++) {
            free(im->pixels[i]);
        }
        free(im->pixels);
        free(im);
    }
}

注意:我不明白保留是什么意思,所以我忽略了它......


(*) 实际上可以一次性分配整个数组,然后让指向行的指针指向全局数组中每一行的开头,但这是一种高级方法...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。