简体   繁体   English

在 C 中动态分配结构的二维数组

[英]dynamically allocate 2d array of structs in C

(corrected the code after a few good comments pointing out some mistakes in the previous version of the code) (在一些好的评论指出之前版本代码中的一些错误后更正了代码)

If I'm right, the best way to dynamically allocate a 2D array of structs in C is the following:如果我是对的,在 C 中动态分配结构的二维数组的最佳方法如下:

    struct xx(*array2d)[y] = malloc(sizeof(struct xx[x][y]));

Does it make any difference whether I store the structs in the array or store pointers to them?将结构存储在数组中还是存储指向它们的指针有什么区别吗?

I was also wondering if I may simply deallocate the allocated memory in the following way:我还想知道我是否可以通过以下方式简单地释放分配的 memory:

void free2d(int x, int y, struct xx array2d[x][y]) {
        free(array2d);
    }

Identifiers in C cannot begin with numbers so 2darray won't work. C 中的标识符不能以数字开头,因此2darray不起作用。

Formally, the most correct way to allocated a 2D array dynamically is:形式上,动态分配二维数组的最正确方法是:

struct xx (*array)[x][y] = malloc(sizeof(struct xx[x][y]));

However that makes accessing the array cumbersome, because we would have to de-reference the array pointer first:然而,这使得访问数组变得很麻烦,因为我们必须首先取消引用数组指针:

(*array)[i][j]

A common trick to avoid this is to have the array pointer not point at the "whole" 2D array, but to the first item.避免这种情况的一个常见技巧是让数组指针不指向“整个”二维数组,而是指向第一项。 Which would be a struct xx [y] array in this case.在这种情况下,这将是一个struct xx [y]数组。

So we can use a pointer to the first element but still allocate the correct amount:所以我们可以使用指向第一个元素的指针,但仍然分配正确的数量:

struct xx (*array)[y] = malloc(sizeof(struct xx[x][y]));

And now we can use this as现在我们可以将其用作

array[i][j] 

In either of the two examples above, you free it with a single free(array) call.在上面的两个示例中,您可以通过一次free(array)调用来释放它。

The allocation code is a bit incorrect.分配代码有点不正确。

  • variable name cannot start with a digit, thus identifier 2darray is illegal.变量名不能以数字开头,因此标识符2darray是非法的。 Use array2d instead改用array2d
  • memory allocation code look almost correct. memory 分配代码看起来几乎正确。 Note that array2d would be a pointer to array of x elements of type struct xx .请注意, array2d将是指向struct xx类型的x元素数组的指针。 Thus the correct allocation code swap order of x and y in sizeof expression.因此在 sizeof 表达式中xy的正确分配代码交换顺序。
struct xx (*array2d)[x] = malloc(sizeof(struct xx[y][x]));

If you want x be the first dimensions use:如果您希望x成为第一个维度,请使用:

struct xx (*array2d)[y] = malloc(sizeof(struct xx[x][y]));

Personally I prefer to use the following pattern because it is less error prone:我个人更喜欢使用以下模式,因为它不易出错:

struct xx (*array2d)[x] = calloc(y, sizeof *array2d);
  1. Passing to function.传递给 function。 It is simple, just pass array dimensions as arguments and then the array itself.这很简单,只需将数组维度作为 arguments 传递,然后传递数组本身。
void foo(int x, int y, struct xx array2d[static x][y]) {

Note that parameter array2d is actually a pointer to array.请注意,参数array2d实际上是指向数组的指针。 The "static extent" tells the compiler that at least x elements pointer by the pointer are valid. “静态范围”告诉编译器指针所指向的至少x元素是有效的。 It is very useful for documentation.它对文档非常有用。 Moreover static makes the declaration visually distinct from a declaration of an array.此外, static使声明在视觉上与数组声明不同。

  1. Deallocation.解除分配。 The free2d function could be used if it followed the pattern from point 2. However I recommend simply using free(array2d);如果它遵循第 2 点的模式,则可以使用free2d function。但是我建议简单地使用free(array2d);

I would use objects instead of types.我会使用对象而不是类型。

struct xx(*array2d)[cols] = malloc(rows *sizeof(*array2D));

To deallocate you do not need sizes only void pointer to your array要解除分配,您不需要大小,只需指向数组的void指针

void free2d(void *array2d) {
        free(array2d);
    }

or simple use free with your pointer to the array.或使用指向数组的指针简单地使用free

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM