在调用malloc之后,p如何成为二维数组?

时间:2012-09-22 03:41:33

标签: c arrays malloc

以下代码段使用malloc函数

声明 4 X 10 的二维数组

/* Declare a pointer to an array that has 10
ints in each row. */
int (*p)[10];
register int i, j;
/* allocate memory to hold a 4 x 10 array */
p = malloc(40*sizeof(int));

但我不明白p如何成为二维数组。最初,p被声明为指向int的指针数组。调用malloc后会发生什么?我无法理解这一点。

3 个答案:

答案 0 :(得分:3)

值为40英寸的内存保留给指针p。 p指着他的记忆块。碰巧的是,p选择将这个记忆组织成10个相等的部分,每个部分碰巧有4个整体值。

如果这段代码实际上是正确的话。我的C在这一点上非常生疏。

答案 1 :(得分:3)

在C中,尽管看起来非常相似,但指针和数组并不相同。这里p的类型为“指向10个整数的数组的指针”。你正在使用它作为“4个10个整数数组的指针”,这是一个单独的内存块(唯一的指针是最外面的指针)。它基本上是动态分配的int[4][10]

阅读这些定义的诀窍是要意识到它们的编写方式与使用该项目的方式相同。如果你有:

*x[10];

首先应用数组下标,然后指针取消引用。因此,如果您定义int *x[10],它就是一个指针数组。如果使用括号覆盖正常优先级,则可以首先发生指针取消引用,因此您有一个指向数组的指针。

混淆?它变得更糟。在函数参数中,函数参数的最外层数组被转换为指针。

int *p[10]; // array of 10 pointer to int
int (*p)[10]; // pointer to array of 10 ints
void foo(int *p[10] /* pointer to pointer to int */);
void foo(int (*p)[10] /* pointer to array of 10 ints */);

此外,当您使用数组时,数组将转换为指针。

int x[10]; // array of 10 int
sizeof(x); // 10 * sizeof(int)
int *y = x; // implicitly converts to a pointer to &x[0]!
sizeof(y); // sizeof(int *)

这意味着你可以为一个数组数组分配内存,然后让它隐式转换为一个指向数组的指针,而你又使用它作为一个数组数组!

无论如何,这一切都非常混乱,所以请不要在生产代码中使用它 - 至少,不是没有澄清的typedef:

typedef int vector[3];
vector *array_of_vectors; // actually a pointer to a vector, 
                          // but you can use it as an aray to a vector if enough
                          // memory is allocated

答案 2 :(得分:0)

首先,一些背景信息:

除非它是sizeof_Alignof或一元&运算符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,类型“T的N元素数组”被转换(“衰减”)为“指向T的指针”类型的表达式,其值是数组中第一个元素的地址。例如,给定数组

int a[10];

表达式a出现在代码中的任何时候,其类型将从“{10}元素int数组”转换为“指向int”,或{{1}对于int *sizeof a_Alignof a等案例,除了。如果我们有一个T的2D数组,例如

&a

表达式int a[10][10]; 将从类型“10元素数组a”的“10元素数组”转换为“指向int的10元素数组的指针”或< strong> int (看起来很熟悉?这是指针int (*)[10]的类型)。

如果我们想动态分配类型p的N元素数组,我们会写类似

的内容
T

T *p = malloc(N * sizeof *p); 相当于sizeof *p。在此特定情况下,类型sizeof (T)是“{元素{1}}的10元素数组”或T。我们想分配4个这样的数组,所以我们可以编写

int

这为int [10]的4个10元素数组分配空间,并将结果分配给int (*p)[10]; p = malloc(4 * sizeof *p); 。 (int)。

那么它如何成为2D阵列?

请注意,p表达式等同于sizeof *p == sizeof (int [10]);我们在a[i]之后找到*(a + i)类型的i'元素的地址,并取消引用结果。在这种情况下,T为我们提供了a之后的p[i] 10元素i 数组的地址。由于我们将指针取消引用作为下标操作的一部分,因此表达式int类型是“{元素p的10元素数组”。因此我们可以再次下标这个表达式并获得p[i]