【问题标题】:Pointer indirection with an array使用数组的指针间接寻址
【发布时间】:2015-12-02 12:53:55
【问题描述】:

我正在尝试使用三个级别的指针间接,并附加一个指向第二级间接的指针。这是一堂课,我遇到了一些真正的问题。这就是我正在做的。

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

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

***s = 1;

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

【问题讨论】:

  • 不确定您到底想要什么。您在寻找 3d 数组吗?
  • 最终游戏是一个二维数组,垂直数组充满指针,列充满变量。
  • 为什么不用int matrix[x][y]来初始化一个二维数组呢?我不明白你所说的 vertical array full of pointers 是什么意思。
  • 正确的方向:Three star programming.
  • 为了效率和简单性,通常最好将 2d 或 3d 数组实现为单个平面数组并使用索引计算。您可以将其包装在一个类中。

标签: c++ arrays pointers dynamic indirection


【解决方案1】:

你已经创建了这样的东西(假设 row 是 2 并输入 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 本身(第一个框)是一个自动变量(通常存储在堆栈空间中),其余来自 freestore(通常是活在堆中)。

Live example.

【讨论】:

  • 天啊。这是设置这种对数组的间接数量的唯一方法吗?
  • 为了清楚起见,我展示了每个步骤,现在添加了较短的版本。
  • 我开始认为我做这个作业是非常错误的。我不能只在黑框里设置int指针,在黄框里最后有一个数组吗?
  • 是的,你可以。立即查看答案。
【解决方案2】:

在这个例子中我们假设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) 尝试取消引用无效的垃圾指针(并且经常崩溃)。

【讨论】:

  • 好的,当我尝试这个时,我使用了cout << **s[0];,我得到了 1,但是当我尝试使用 ***(s + 1) = 2; 在下一个偏移量中存储一些东西时,它不起作用,为什么不呢?
  • @Mishap 因为*(s + 1)(也称为s[1])仍未初始化且不是有效指针(请参阅我编辑的答案)。
猜你喜欢
  • 2011-06-02
  • 1970-01-01
  • 2012-07-15
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多