使用结构的二维内存分配
2D memory allocation using structure
// 我必须创建一个新的 imgr_t,其中包含初始大小的行、列及其保留对应项(行和 reserved_rows 将相同,列和 reserved_cols 相同)。如果分配成功(即内存分配成功),returns 一个指向新分配的 imgr_t 的指针,如果不成功,returns 一个空指针。
#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
。您还需要分配一些 space 来存储您的像素:
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
时也是如此)。
这里你需要:
imgr_t
结构 的 1 个分配
- 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);
}
}
注意:我无法理解 reserved 的意思,所以我忽略它...
(*) 事实上,可以一次分配整个数组,然后将指向行的指针指向全局数组中每一行的开头,但这是一种高级方法...
// 我必须创建一个新的 imgr_t,其中包含初始大小的行、列及其保留对应项(行和 reserved_rows 将相同,列和 reserved_cols 相同)。如果分配成功(即内存分配成功),returns 一个指向新分配的 imgr_t 的指针,如果不成功,returns 一个空指针。
#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
。您还需要分配一些 space 来存储您的像素:
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
时也是如此)。
这里你需要:
imgr_t
结构 的 1 个分配
- 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);
}
}
注意:我无法理解 reserved 的意思,所以我忽略它...
(*) 事实上,可以一次分配整个数组,然后将指向行的指针指向全局数组中每一行的开头,但这是一种高级方法...