使用数组的指针间接寻址

Pointer indirection with an array

我正在尝试使用一个指向二级间接寻址的附加指针来实现三级指针间接寻址。这是针对 class 的,我遇到了一些实际问题。这就是我正在做的。

int ***s = new int **[row];
*s = new int *[row];
**s = new int[row];

现在如果这些只是 int 而不是我可以做的数组,

***s = 1;

要将它存储到我图片上的黄色方块中,但我不知道如何访问数组元素,我尝试了一些方法,它要么崩溃,要么无法编译。任何帮助,甚至为我指明正确的方向都会非常有用。谢谢。

让我们假设这个例子是 row = 3

int ***s;
// s=[?]
// s is an uninitialized variable.

s = new int **[row];
// s[*] -> [?]
//         [?]
//         [?]
// s points to the first element of an array of size 3.
// The elements are uninitialized.

*s = new int *[row];
// s=[*] -> [*] -> [?]
//          [?]    [?]
//          [?]    [?]
// We've initialized s[0]. It points to another array of size 3.
// All elements of that array are also uninitialized, along with s[1] and s[2].

**s = new int[row];
// s=[*] -> [*] -> [*] -> [?]
//          [?]    [?]    [?]
//          [?]    [?]    [?]
// More of the same. s[0][0] is initialized.
// This last array contains uninitialized ints, not pointers.

***s = 1;
// s=[*] -> [*] -> [*] -> [1]
//          [?]    [?]    [?]
//          [?]    [?]    [?]
// We traverse three levels of pointers (->) and store 1 in the cell.

所有这些都应该可以编译并正常工作(只要您不访问任何未初始化的元素)。


s + 1指向第一个数组的第二个元素。

// s=[*] -> [*] -> [*] -> [1]
// s + 1 -> [?]    [?]    [?]
//          [?]    [?]    [?]

*(s + 1)指的是上图中s + 1指向的单元格[?]。此单元格未初始化。

**(s + 1) 尝试取消引用垃圾指针,这是无效的(并且经常崩溃)。

你已经创建了这样的东西(假设 row 是 2 并输入 T):

                           T***
                          +-----+
                          |     |
                          +--/--+
                            /
                           / T**
                       +--/--+-----+
                       |     |     |
                       +-----+--+--+
                       -/       |
                    --/      T* |
                +--/--+-----+ +-+---+-----+
                |     |     | |     |     |
                +-----+-----+ +--+--+-----+
            ----/      -/        |      \---
      -----/        --/      T   |          \--
  +--/--+-----+ +--/--+-----+ +--+--+-----+ +--\--+-----+
  |     |     | |  X  |     | |     |     | |     |     |
  +-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+

每个节点都会指向下一层的第一个节点。取消引用每个级别都会给出下一个级别,但您还必须处理要到达的数组中元素的索引。我明白了,这不是在您的代码中完成的。对于标量,您使用 * 取消引用,而对于数组,除了选择正确的元素之外,数组索引语法也会取消引用。 * 在数组上总是让你得到第一个元素。

要访问上图中的 X,您需要这样做

T** v = u[0];
T* w = v[1];
T x = w[0];
// shorthand for above
x = u[0][1][0];

要在最后一级有一个数组,你应该这样做

int*** p = new int**;
*p = new int*;
**p = new int[row];

这只会给你 █ → █ → █ → █ █ █ …,其中 p 本身(第一个框)是一个自动变量(通常存储在堆栈 space 中)并且其余来自自由商店(通常生活在堆中)。

Live example.