在堆中分配 C 中的二维数组(不是指针数组)
Allocate 2D Array in C (not array of pointers) in Heap
我有一个简单的问题,但答案似乎很难找到:
如何在堆上用 C(不是 C++)创建一个动态大小(编译时不知道大小)而不是指针数组的真正二维数组,以便我可以将该分配放入单独的函数和 return 分配的数组,没有收到来自 gcc -Wall
?
的任何警告
我在 SO 和其他论坛上发现了许多其他问题,但答案都有一些缺陷:
- 我看到了很多答案,其中展示了如何初始化一个指针数组,根据一些评论,这会导致内存碎片,并且在不再使用时需要一个循环来释放。
- 我不想只有预定义大小的数组,而是想在某些循环中使用它,创建多种大小的数组。
- 我也不希望数组中的值是预定义的,它们是在程序运行时计算的 运行。
- 我读到内存中的布局,使用一些创建数组的方法时可能会有所不同,但仍然可以像这样使用数组:
a[y][x]
。我希望我的阵列也具有真正的二维阵列的内存布局。
实现这样一个真正的二维数组分配的正确方法是什么?
编辑#1:
分配方法的return类型可以是指向分配数组的指针。
我知道这不是完美的答案;但我希望它会有所帮助。
#include <stdio.h>
#include <stdlib.h>
#define ELEM(myArr,X,Y) (myArr->arr[myArr->cols * X + Y])
#define FREE_MY_ARR(myArr) \
if(myArr){if(myArr->arr) free(myArr->arr); free(myArr);}
typedef struct myArr
{
int rows , cols;
int * arr;
} myArr;
myArr * create_my_arr(int rows , int cols)
{
myArr * my_arr = malloc(sizeof(myArr));
my_arr->rows =rows;
my_arr->cols=cols;
my_arr->arr= malloc(rows * cols * sizeof(*my_arr->arr));
return my_arr;
}
int main()
{
int rows = 4 , cols = 5;
myArr * my_arr = create_my_arr(4,5);
int i , j ;
for(i = 0 ; i < rows;i++)
for(j = 0 ; j < cols;j++)
{
ELEM(my_arr , i , j) = cols * i + j; // 0,1,2,3,4,5,6,7,8,...etc
}
//print array.
for(i = 0 ; i < rows;i++)
{
for(j = 0 ; j < cols;j++)
{
printf("arr[%d,%d]=%d\t" , i , j , ELEM(my_arr ,i , j));
}
printf("\n");
}
FREE_MY_ARR(my_arr);
return 0;
}
输出:
gcc -o s s.c &&s
arr[0,0]=0 arr[0,1]=1 arr[0,2]=2 arr[0,3]=3 arr[0,4]=4
arr[1,0]=5 arr[1,1]=6 arr[1,2]=7 arr[1,3]=8 arr[1,4]=9
arr[2,0]=10 arr[2,1]=11 arr[2,2]=12 arr[2,3]=13 arr[2,4]=14
arr[3,0]=15 arr[3,1]=16 arr[3,2]=17 arr[3,3]=18 arr[3,4]=19
您不需要特殊功能。就这样做吧
double (*A)[n][m] = malloc(sizeof *A);
从 C99 开始,这里的 n
和 m
可以是您想要的任何正整数表达式。
这样的东西是指向 VLA 的指针,可变长度数组。
我有一个简单的问题,但答案似乎很难找到:
如何在堆上用 C(不是 C++)创建一个动态大小(编译时不知道大小)而不是指针数组的真正二维数组,以便我可以将该分配放入单独的函数和 return 分配的数组,没有收到来自 gcc -Wall
?
我在 SO 和其他论坛上发现了许多其他问题,但答案都有一些缺陷:
- 我看到了很多答案,其中展示了如何初始化一个指针数组,根据一些评论,这会导致内存碎片,并且在不再使用时需要一个循环来释放。
- 我不想只有预定义大小的数组,而是想在某些循环中使用它,创建多种大小的数组。
- 我也不希望数组中的值是预定义的,它们是在程序运行时计算的 运行。
- 我读到内存中的布局,使用一些创建数组的方法时可能会有所不同,但仍然可以像这样使用数组:
a[y][x]
。我希望我的阵列也具有真正的二维阵列的内存布局。
实现这样一个真正的二维数组分配的正确方法是什么?
编辑#1: 分配方法的return类型可以是指向分配数组的指针。
我知道这不是完美的答案;但我希望它会有所帮助。
#include <stdio.h>
#include <stdlib.h>
#define ELEM(myArr,X,Y) (myArr->arr[myArr->cols * X + Y])
#define FREE_MY_ARR(myArr) \
if(myArr){if(myArr->arr) free(myArr->arr); free(myArr);}
typedef struct myArr
{
int rows , cols;
int * arr;
} myArr;
myArr * create_my_arr(int rows , int cols)
{
myArr * my_arr = malloc(sizeof(myArr));
my_arr->rows =rows;
my_arr->cols=cols;
my_arr->arr= malloc(rows * cols * sizeof(*my_arr->arr));
return my_arr;
}
int main()
{
int rows = 4 , cols = 5;
myArr * my_arr = create_my_arr(4,5);
int i , j ;
for(i = 0 ; i < rows;i++)
for(j = 0 ; j < cols;j++)
{
ELEM(my_arr , i , j) = cols * i + j; // 0,1,2,3,4,5,6,7,8,...etc
}
//print array.
for(i = 0 ; i < rows;i++)
{
for(j = 0 ; j < cols;j++)
{
printf("arr[%d,%d]=%d\t" , i , j , ELEM(my_arr ,i , j));
}
printf("\n");
}
FREE_MY_ARR(my_arr);
return 0;
}
输出:
gcc -o s s.c &&s
arr[0,0]=0 arr[0,1]=1 arr[0,2]=2 arr[0,3]=3 arr[0,4]=4
arr[1,0]=5 arr[1,1]=6 arr[1,2]=7 arr[1,3]=8 arr[1,4]=9
arr[2,0]=10 arr[2,1]=11 arr[2,2]=12 arr[2,3]=13 arr[2,4]=14
arr[3,0]=15 arr[3,1]=16 arr[3,2]=17 arr[3,3]=18 arr[3,4]=19
您不需要特殊功能。就这样做吧
double (*A)[n][m] = malloc(sizeof *A);
从 C99 开始,这里的 n
和 m
可以是您想要的任何正整数表达式。
这样的东西是指向 VLA 的指针,可变长度数组。