【问题标题】:C++ negative array index [duplicate]C ++负数组索引[重复]
【发布时间】:2018-04-20 14:39:42
【问题描述】:

我分配了一个包含 3 个元素的 int 数组,并想到了下面的代码:

int a[3];
for(int i = -2; i < 3; ++i){
    a[i] = i; 
    cout<<a[i]<<" ";
}

这是它的输出:

-2 -1 0 1 2 

似乎数组 a 有 5 个分配空间,而 a 位于这些空间的中间。 有什么想法吗?

【问题讨论】:

  • C++ 没有数组边界检查。在任一方向上越界索引都会导致undefined behavior
  • @SerkanPekçetin 提出的问题没有具体提到负索引,但原理几乎完全相同。

标签: c++ arrays


【解决方案1】:

要解释负索引的工作原理,您首先必须了解(或记住)对于任何数组或指针a 和索引i,表达式a[i] 等于*(a + i)

这意味着您可以有一个指向数组中间元素的指针,并将其与正或负索引一起使用,这很简单。

例子:

int a[3] = { 1, 2, 3 };
int* p = &a[1];  // Make p point to the second element

std::cout << p[-1];  // Prints the first element of a, equal to *(p - 1)
std::cout << p[ 0];  // Prints the second element of a, equal to *p
std::cout << p[ 1];  // Prints the third element of a, equal to *(p + 1)

有点像图形上的样子

+-----+------+------+ |一个[0] |一个[1] |一个[2] | +-----+------+------+ ^ ^ ^ | | | p-1 p p+1

现在,当在数组中使用负索引时,如问题中a 的示例,它将是这样的:

+-----+-------+--------+------+------+------+ | ... |一个[-2] |一个[-1] |一个[0] |一个[1] |一个[2] | +-----+-------+--------+------+------+------+

也就是说,这里的负索引会超出数组的范围,会导致未定义的行为

【讨论】:

  • 这本身就是真的,但忽略了这样一个事实,即问题中使用的“负”索引不在分配的数组中,并且行为未定义。
  • @TonyDelroy 我在对问题本身的评论中提到了这一点。
  • 很遗憾,因为这是一个很好的答案,正是我来这里寻找的。回答前请仔细阅读问题。
【解决方案2】:

这是你永远不应该做的事情! C++ 不检查内置普通数组的边界,因此从技术上讲,您可以访问超出分配空间的位置(只有 3 个整数而不是 5 个),但最终会产生错误。

【讨论】:

    【解决方案3】:

    当我在自己的 IDE (Visual Studio 2017) 上运行它时,它抛出了一个异常,指出数组周围的堆栈已损坏。我认为正在发生的是正在分配内存中的 3 个空间,但是您强制数组写入 5 个空间,即初始分配之前和之后的空间。这在技术上可行,但绝对不推荐。您基本上是在记忆中的某些内容之上写入内容,并且在大型数组中完成时可能会产生不良后果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-29
      • 2010-10-28
      • 2018-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多