除了@chqrlie的答案,请注意,第二张“半动态”的图片相当令人困惑,你在顶部的图片可以说是更正确的(在任何情况下都没有错)-只需注意,你必须执行array[n]才能访问指针,但*(array[n])首先获得正确的指针,然后取消引用指针并访问实际的项。*(array[n])等于array[n][0]。 int* array[2]是一个2指针数组。此数组在堆栈上分配。每个指针可以被分配为指向单个int项。如果您愿意,这个int可以在堆上分配。它可以是单个项,也可以是int数组中的第一个int,在这种情况下,您需要以某种方式跟踪这些数组的大小。 因此,在int* array[2]的情况下,array[0][1]很可能是越界访问。或者至少访问该项目并不比说array[0][42]更正确或更不正确-这取决于上下文。 “半动态”的图片更正确地说明了一些奇怪的憎恶类型,如 int (*arr[2])[2]; -“An array of pointers to arrays of int with size 2”。不是一个很有帮助的类型为大多数目的和种可笑的难以阅读。 一般来说,我们应该尽可能使用真正的2D数组,即使是在堆上。唯一一次使用指针数组或指向指针数组的指针,是当你有一个特殊的容器,它不是一个真正的多维数组,而是具有单独维度大小的东西(有时称为“锯齿数组”)。一个例子是在堆上分配的字符串数组--使用char**和malloc来实现它是非常有意义的。 指针数组/指针查找表等的缺点是我们得到分段分配,这比真实的的多维数组访问和分配慢得多。而且在某些情况下也不必要地复杂。查看Correctly allocating multi-dimensional arrays了解详细信息。
arr = malloc( sizeof *arr * M ); // Allocates space for M pointers to int
for ( size_t i = 0; i < M; i++ )
arr[i] = malloc( sizeof *arr[i] * N ); // Allocates space for N ints.
3条答案
按热度按时间lsmepo6l1#
除了@chqrlie的答案,请注意,第二张“半动态”的图片相当令人困惑,你在顶部的图片可以说是更正确的(在任何情况下都没有错)-只需注意,你必须执行
array[n]
才能访问指针,但*(array[n])
首先获得正确的指针,然后取消引用指针并访问实际的项。*(array[n])
等于array[n][0]
。int* array[2]
是一个2指针数组。此数组在堆栈上分配。每个指针可以被分配为指向单个int
项。如果您愿意,这个int
可以在堆上分配。它可以是单个项,也可以是int
数组中的第一个int
,在这种情况下,您需要以某种方式跟踪这些数组的大小。因此,在
int* array[2]
的情况下,array[0][1]
很可能是越界访问。或者至少访问该项目并不比说array[0][42]
更正确或更不正确-这取决于上下文。“半动态”的图片更正确地说明了一些奇怪的憎恶类型,如
int (*arr[2])[2];
-“An array of pointers to arrays of int with size 2”。不是一个很有帮助的类型为大多数目的和种可笑的难以阅读。一般来说,我们应该尽可能使用真正的2D数组,即使是在堆上。唯一一次使用指针数组或指向指针数组的指针,是当你有一个特殊的容器,它不是一个真正的多维数组,而是具有单独维度大小的东西(有时称为“锯齿数组”)。一个例子是在堆上分配的字符串数组--使用
char**
和malloc
来实现它是非常有意义的。指针数组/指针查找表等的缺点是我们得到分段分配,这比真实的的多维数组访问和分配慢得多。而且在某些情况下也不必要地复杂。查看Correctly allocating multi-dimensional arrays了解详细信息。
cxfofazt2#
您的理解是正确的,并且确实对应于一个指向
int
的指针数组,该数组是用自动存储(在堆栈上)定义的,在类图中被描述为一个 * 半动态 * 数组。类中显示的图表描述了具有不同布局的2种其他类型的数组:
int
的阵列的阵列。这个维度不需要进一步的分配,并且两个维度都在编译时固定。array
作为指向int的指针,int **array;
。要使用这种类型的存储,您需要分配指针数组和每个指针指向的数组。这两个维度都可以在运行时确定,但是访问的开销稍微高一些,因为需要2个间接访问int
值。取决于实际实现,编译器可能能够优化若干连续访问,从而分解出一些冗余代码。请注意,上述对象具有不同的布局,虽然您可以使用相同的语法
array[row][col]
访问元素进行阅读和写入,但您不能将这些数组作为参数传递给相同的函数。57hvy0tb3#
你被一些非传统的术语引入歧途了。2D数组总是 * 声明为
并且该声明可以读作“
arr
是N
的M
元素数组T
的M
元素数组”。你的“半动态”数组是一个一维数组 * 指针 *:
每个元素 * 可以 * 指向另一个数组的第一个元素(无论是否动态分配)
和你的“全动态”数组
不是一个数组。只是个指针。它 * 可能 * 指向指针数组的第一个元素(动态分配或非动态分配),其中每个元素 * 可能 * 指向数组的第一个元素(动态分配或非动态分配):
假设
M
和N
是2
,则您的2D阵列将布局为而您的1D指针数组将被布局为
而你的指针到指针版本看起来就像
同样,没有任何规则要求指针必须指向动态分配的内存。以下也是有效的(尽管我目前没有一个很好的用例):
这就给了我们
x
和y
不是动态分配的;它们是与arr
相同的存储类。