有几种方法可以为 NxM 数组动态分配内存。这里有两个:
您可以声明一个指向 M 元素数组的指针,然后声明malloc
它的 N 个实例:
double (*podrucje)[11] = malloc(sizeof *podrucje * 123);
从 C89 开始,您不需要强制转换 的结果malloc
,并且不鼓励这种做法。另外,请注意操作数sizeof
是表达式*podrucje
; 这给了我相同的结果sizeof (double) * 11
。
podrucje[i][j]
您可以像任何其他二维数组一样 索引这个数组。podrucje[i]
隐式取消引用指针(记住它a[i]
相当于*(a + i)
),因此您不必对它做任何时髦的事情。
您将在如下函数中使用它:
void init(double (*podrucje)[11], size_t rows)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < 11; j++)
podrucje[i][j] = 0.0;
}
这将被称为
init(podrucje, 123);
这种方法的缺点是该函数只能对 Nx11 数组进行操作;如果您使用的是支持可变长度数组的 C99 编译器或 C2011 编译器,则可以将列数指定为运行时变量:
void foo(void)
{
size_t rows = 123, cols = 11;
double (*podrucje)[cols] = malloc(sizeof *podrucje * rows);
if (podrucje)
init(cols, podrucje, rows);
...
}
// cols must be declared before it can be used
// in an array declarator
//
void init(size_t cols, double(*podrucje)[cols], size_t rows)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
podrucje[i][j] = 0.0;
}
完成数组后,按如下方式释放它:
free(podrucje);
另一种方法是单独分配每一行,如下:
size_t rows = 123, cols = 11;
double **podrucje = malloc(sizeof *podrucje * rows);
if (!podrucje)
{
// malloc failed; handle allocation error here
}
else
{
size_t i;
for (i = 0; i < rows; i++)
{
podrucje[i] = malloc(sizeof *podrucje[i] * cols);
if (!podrucje[i])
{
// malloc failed; handle allocation error here
}
}
}
您将在如下函数中使用它:
void foo()
{
double **podrucje;
// allocate array as above
init(foo, rows, cols);
...
}
void init(double **podrucje, size_t rows, size_t cols)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
podrucje[i][j] = 0.0;
}
完成数组后,按如下方式释放它:
for(i = 0; i < rows; i++)
free(podrucje[i]);
free(podrucje);
第一种方法将内存分配为单个连续块;第二个将它分配在一系列更小的、不连续的块中。如果你的数组特别大或者你的堆特别碎片,第一种方法可能会失败,而第二种方法会成功。如果您使用的编译器不支持可变长度数组,则第一种方法的灵活性要低得多,因为必须在编译时指定列数。
相同的索引方法如何适用于两种形式?
在第一种情况下,每个podrucje[i]
都是 11 个元素的数组double
;j
像任何其他数组一样使用索引它。在第二种情况下, eachpodrucje[i]
是一个指向 double 的指针。由于a[i]
被评估为*(a + i)
,因此数组索引对指针表达式和数组表达式一样有效。