指向数组中指针的指针

Pointers to pointers in arrays

本文关键字:指针 数组      更新时间:2023-10-16

我有一个关于C++中的指针和数组的问题。我不确定这部分代码到底在做什么。在我看来,iarray 被声明为普通数组。但是,q被访问就像一个2d数组一样。

int iarray[10];
int *p = iarray;
int **q = &p;
q[0][2] = 25;

如果我将 iarray 更改为:

int iarray[10]{3,2};
int *p = iarray;
int **q = &p;
q[0][2] = 25;
cout << q[0][0] << endl;
cout << q[1][0] << endl;

第一个将打印 3,我在上面声明时理解。但是第二个是空白的,我不明白为什么。

让我们一次看一条指令:

int iarray[10];将在内存中保留 10 个整数大小的字节。如果sizeof(int) == 4,它将保留 40 个字节。假设内存范围设置在 0x10 - 0x37 之间。

int *p = iarray保留 4 个字节(如果我们假设我们在 32 位处理器上运行),并将起始地址存储到上一条指令中保留的 40 个字节。p是我们用来指代这 4 个字节的简写。假设这 4 个字节存储在 0x50 - 0x53。

int **q = &p保留 4 个字节,用于保存 p (0x50) 的起始地址。 Q 可以存储在 0x60-0x63 处。

指针上的 c++ 中的数组索引运算符是指针算术的简写。例如,q[N]*(q + N)是一回事,因此,在我的示例中,q[0]将为您提供在地址 0x60-0x63 处持有的值,即0x50。 如果再次使用 index 运算符,它将应用于新地址 (0x50),因此q[0][2]等效于p[2],即iarray[2]

q[1]相当于*(q + 1) = *(0x60 + 0x4) =*(0x64)。如果你看上面,我们从不保留地址0x64,所以我们从我们不拥有的内存中读取 - 未定义的行为。

让我们来看看这个:

int iarray[10]; // declare a array of 10 ints
int *p = iarray; // p is used like an alias for iarray, an int[] is also an int*
int **q = &p; //q is a pointer to pointer p

q仅指向单个值。您可以将q想象成一个只有一个条目的数组。您也可以将其写为int *q[] = { &p };

因此q[1][0]是未定义的行为,因为q[1]已经超出了界限。