在 C 中动态分配二维结构数组
dynamically allocate 2d array of structs in C
(在指出之前版本代码中的一些错误的一些好的评论后更正了代码)
如果我是对的,在 C 中动态分配结构的二维数组的最佳方法如下:
struct xx(*array2d)[y] = malloc(sizeof(struct xx[x][y]));
将结构存储在数组中或存储指向它们的指针有什么区别吗?
我也想知道我是否可以通过以下方式简单地释放分配的内存:
void free2d(int x, int y, struct xx array2d[x][y]) {
free(array2d);
}
分配代码有点不正确。
- 变量名不能以数字开头,因此标识符
2darray
是非法的。使用 array2d
代替
- 内存分配代码看起来几乎是正确的。请注意,
array2d
将是指向类型 struct xx
的 x
元素数组的指针。因此 sizeof 表达式中 x
和 y
的正确分配代码交换顺序。
struct xx (*array2d)[x] = malloc(sizeof(struct xx[y][x]));
如果您希望 x
成为第一个维度,请使用:
struct xx (*array2d)[y] = malloc(sizeof(struct xx[x][y]));
我个人更喜欢使用以下模式,因为它不太容易出错:
struct xx (*array2d)[x] = calloc(y, sizeof *array2d);
- 正在传递函数。很简单,只需传递数组维度作为参数,然后传递数组本身。
void foo(int x, int y, struct xx array2d[static x][y]) {
注意参数array2d
实际上是一个指向数组的指针。 “静态范围”告诉编译器指针指向的至少 x
个元素是有效的。它对文档非常有用。此外 static
使声明在视觉上与数组声明不同。
- 取消分配。如果遵循第 2 点的模式,则可以使用
free2d
函数。但是我建议只使用 free(array2d);
C 中的标识符不能以数字开头,因此 2darray
无效。
形式上,动态分配二维数组最正确的方法是:
struct xx (*array)[x][y] = malloc(sizeof(struct xx[x][y]));
但是 这使得访问数组很麻烦,因为我们必须先取消引用数组指针:
(*array)[i][j]
避免这种情况的一个常见技巧是让数组指针不指向“整个”二维数组,而是指向第一项。在这种情况下,这将是一个 struct xx [y]
数组。
所以我们可以使用指向第一个元素的指针,但仍然分配正确的数量:
struct xx (*array)[y] = malloc(sizeof(struct xx[x][y]));
现在我们可以将其用作
array[i][j]
在上面两个示例中的任何一个中,您都可以通过单个 free(array)
调用将其释放。
我会使用对象而不是类型。
struct xx(*array2d)[cols] = malloc(rows *sizeof(*array2D));
要解除分配,您不需要大小 void
指向数组的指针
void free2d(void *array2d) {
free(array2d);
}
或者简单地使用 free
和指向数组的指针。
(在指出之前版本代码中的一些错误的一些好的评论后更正了代码)
如果我是对的,在 C 中动态分配结构的二维数组的最佳方法如下:
struct xx(*array2d)[y] = malloc(sizeof(struct xx[x][y]));
将结构存储在数组中或存储指向它们的指针有什么区别吗?
我也想知道我是否可以通过以下方式简单地释放分配的内存:
void free2d(int x, int y, struct xx array2d[x][y]) {
free(array2d);
}
分配代码有点不正确。
- 变量名不能以数字开头,因此标识符
2darray
是非法的。使用array2d
代替 - 内存分配代码看起来几乎是正确的。请注意,
array2d
将是指向类型struct xx
的x
元素数组的指针。因此 sizeof 表达式中x
和y
的正确分配代码交换顺序。
struct xx (*array2d)[x] = malloc(sizeof(struct xx[y][x]));
如果您希望 x
成为第一个维度,请使用:
struct xx (*array2d)[y] = malloc(sizeof(struct xx[x][y]));
我个人更喜欢使用以下模式,因为它不太容易出错:
struct xx (*array2d)[x] = calloc(y, sizeof *array2d);
- 正在传递函数。很简单,只需传递数组维度作为参数,然后传递数组本身。
void foo(int x, int y, struct xx array2d[static x][y]) {
注意参数array2d
实际上是一个指向数组的指针。 “静态范围”告诉编译器指针指向的至少 x
个元素是有效的。它对文档非常有用。此外 static
使声明在视觉上与数组声明不同。
- 取消分配。如果遵循第 2 点的模式,则可以使用
free2d
函数。但是我建议只使用free(array2d);
C 中的标识符不能以数字开头,因此 2darray
无效。
形式上,动态分配二维数组最正确的方法是:
struct xx (*array)[x][y] = malloc(sizeof(struct xx[x][y]));
但是 这使得访问数组很麻烦,因为我们必须先取消引用数组指针:
(*array)[i][j]
避免这种情况的一个常见技巧是让数组指针不指向“整个”二维数组,而是指向第一项。在这种情况下,这将是一个 struct xx [y]
数组。
所以我们可以使用指向第一个元素的指针,但仍然分配正确的数量:
struct xx (*array)[y] = malloc(sizeof(struct xx[x][y]));
现在我们可以将其用作
array[i][j]
在上面两个示例中的任何一个中,您都可以通过单个 free(array)
调用将其释放。
我会使用对象而不是类型。
struct xx(*array2d)[cols] = malloc(rows *sizeof(*array2D));
要解除分配,您不需要大小 void
指向数组的指针
void free2d(void *array2d) {
free(array2d);
}
或者简单地使用 free
和指向数组的指针。