[英]How to malloc a 2d jagged array using a pointer passed by reference to a function in C
I have a 2D jagged array declared in my main()
block. 我在
main()
块中声明了一个2D锯齿状数组。 This is to be passed to a function to have memory allocated to it. 这将被传递给一个函数,以便为其分配内存。 The following is the most reduced case which compiles but crashes when it runs.
以下是最简化的情况,它会在运行时编译但崩溃。 Where am I going wrong?
我哪里错了?
#include <stdio.h>
#include <stdlib.h>
void alloc2d(double ***p);
int main () {
double **data;
alloc2d(&data);
printf("Before assign to data\n");
data[0][0] = 0.1;
printf("After assign to data\n");
free(data);
}
void alloc2d(double ***p) {
int i, n, m;
// Get some dynamically assigned sizes
printf("Enter size: ");
scanf("%d %d", &n, &m);
// Now allocate
*p = malloc(n * sizeof(double*));
for (i = 0; i < n; i++) {
*p[i] = malloc(m * sizeof(double));
}
printf("End of alloc2d\n");
}
This reads the values but crashes when I enter low numbers (ie '1 1') but crashes when I enter high numbers (ie '10 10'). 这会读取值,但是当我输入低数字(即'1 1')时会崩溃,但是当我输入高数字(即'10 10')时会崩溃。
You made a very simple syntax error 你做了一个非常简单的语法错误
*p[i] = (double*)malloc(m * sizeof(double));
should really be 应该真的
(*p)[i] = (double*)malloc(m * sizeof(double));
This is because in C, [] operator has higher precedence than *. 这是因为在C中,[]运算符的优先级高于*。 So when you type
*p[i]
, it is translated into **(p + i)
. 所以当你输入
*p[i]
,它被翻译成**(p + i)
。
This means: you are asking the compiler to calculate the address by offsetting the address of p by i * sizeof(double**)
, which is clearly not what you actually want. 这意味着:你要求编译器通过将p的地址偏移
i * sizeof(double**)
来计算地址,这显然不是你真正想要的。
So, in order to force the compiler to dereference p first, simply surroud *p
with brackets. 因此,为了强制编译取消引用p个第一,只是surroud
*p
与支架。
Operator precedence is the answer. 运算符优先级就是答案。
*p[i]
is equivalent to *(p[i])
. *p[i]
相当于*(p[i])
。 This makes you access memory that lies right after the data
pointer, which will either corrupt some other variables on the stack, or crash completely. 这使您可以访问位于
data
指针之后的内存,这将破坏堆栈上的其他一些变量,或者完全崩溃。
You were looking for (*p)[i]
, which will be the i-th entry in the newly allocated array. 您正在寻找
(*p)[i]
,这将是新分配的数组中的第i个条目。
What your alloc2d() allocates is not really a 2D array, but: 您的alloc2d()分配的内容实际上不是2D数组,但是:
Multi-dimensional arrays in C are only possible, if all but the last of the dimensions are known at compile-time: C中的多维数组只有在编译时才能知道除最后一个维之外的所有维数:
double a[5][11];
Maybe, this program can help you understand... Note, how COLUMNS is a compile-time constant, even if rows is a run-time variable: 也许,这个程序可以帮助你理解......注意,COLUMNS是一个编译时常量,即使rows是一个运行时变量:
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <err.h>
typedef double myrow_t[11]; /* 11 columns */
#define COLUMNS (sizeof(myrow_t)/sizeof(double))
static unsigned
alloc2d(myrow_t **pd)
{
unsigned int rows;
printf("Enter the number of rows: ");
while (scanf("%u", &rows) != 1)
printf("\ninvalid input, please, try again: ");
*pd = malloc(rows * sizeof(**pd));
if (*pd == NULL)
err(EX_TEMPFAIL, "Out of memory");
return rows;
}
int
main()
{
myrow_t *d;
unsigned int row, column, rows;
rows = alloc2d(&d);
for (row = 0; row < rows; row++)
for (column = 0; column < COLUMNS; column++)
d[row][column] = row * column;
for (row = 0; row < rows; row++) {
printf("Row %3d:\t", row);
for (column = 0; column < COLUMNS; column++)
printf("%.0f\t", d[row][column]);
puts("");
}
free(d);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.