指向2d数组和分配的指针

Pointer to 2d Array and allocation

本文关键字:指针 分配 2d 数组 指向      更新时间:2023-10-16

阅读这个问题:int*x[n][m]和int(*x)[n][m]之间有什么区别?

正确的答复是:

int arr[2][3];
int (*p1)[2][3] = &arr;  // arr decays to int(*)[3], so we need to take the address
int (*p2)[2][3] = new int[42][2][3]; // allocate 42 arrays dynamically

最后一行的注释说它分配了42个新数组。这是怎么回事?有人能给我解释一下吗?

谢谢!

我会回答这个问题,但我不能,所以这是一个新问题(:

new int[3]分配3个整数。现在new int[2][3]分配2个数组,每个数组的长度为3个整数。进一步扩展,new int[42][2][2]分配42个数组,每个数组的长度为2,每个数组又是长度为2的整数。声明实际上是一个递归的想法。

好吧,上课时间。

C++多维数组与锯齿数组

多校正数组(在C++中)是一个连续内存块。它在一行中分配全部数量的元素,然后通过组合索引访问器来访问它们。本质上。如果我有一个由int x[2][3]定义的数组,它本质上将x[i][j]转换为(&x[0][0]+i*3)[j]

sizoef(int[2][3])==24(4字节/int*2*3)

这种类型的数组通常被称为"静态"数组,因为数组的大小必须在编译时分配。

请注意,第一个大小与此查找无关。这样,当引用这种类型的数组时,我们可以从类型中排除最小的大小。这使得下面的两个函数都是有效的,并且可以在上面声明的数组x上工作:

int foo(int y[2][3]){ return y[1][1];}
int bar(int y[][3]){ return y[1][1];}

请注意,在这种情况下,sizeof(y)==sizeof(void*),但这是一个不同的问题。

静态数组的类型约定的行为与过去不同。部分类型信息位于变量声明之后。这种情况实际上也存在于typedefs中:

typedef int a[4][20];
typedef int b[][20];

如果你想获取这样一个值类型的地址,那么你需要声明指向这个数组类型的指针。这可以用来完成

int (*xptr)[2][3] = &x;

int (*var)[...]表示var是指向int[2][3]的指针。

当人们说C++数组是指针时,他们并不是指这种类型的数组:数组比这里的指针更复杂一点,尽管我们可以将其扁平化为1D数组。

锯齿状阵列(或动态阵列)是以线性方式分配的连续存储器的单个块。这种类型的数组通常被称为动态数组,因为在编译时不需要知道其大小。

动态数组是用new或malloc分配的(尽管您应该只在C++中使用new)。这些类型的数组严格意义上的指针。当我说int* a=new int[4]时,我分配了4个整数:就是这样。

我们在这里通过装箱锯齿状数组(指针数组)来实现多点性。例如:

int** a = new int*[2];
for (int i = 0; i < 2; i++) { a[i]=new int[3];}

您的代码的作用

int arr[2][3];//
int (*p1)[2][3] = &arr;  // arr decays to int(*)[3], so we need to take the address
int (*p2)[2][3] = new int[42][2][3]; // allocate a dynamic array (42 elements long) of int[2][3] (sizeof(int[2][3])==24, so this allocates 42*24 bytes!)

它实质上在一行中分配43 int[2][3]。因此,它实际上产生了所有连续的内存(尽管我无法理解为什么它需要是动态的而不是静态的)。

就我个人而言,我的规则是多元素数组"令人困惑",现在只在本地上下文中使用它们,但每个数组都有自己的规则。