超出索引C/C++

Out of index C/C++

本文关键字:C++ 索引      更新时间:2023-10-16

C/C++中数组的典型声明是:

类型名称[元素];

其中type是有效的类型(如int、float…),name是有效的标识符,elements字段(总是用方括号[]括起来)根据元素数量指定数组的长度。

所以我声明一个int数组有两个元素

int a[2];
a[3] =4;

为什么不抛出异常?

越界检查是您可能已经习惯于Java等高级语言的检查。然而,在C/C++中,默认情况下不会这样做。检查数组的边界会给您带来很小的性能打击,因此C的基本原理是让您手动执行,以防您需要它来提供尽可能好的性能。像vector这样的C++STL容器通常支持at()操作来执行绑定检查,并且由于可以重载[]-运算符,因此还可以为数组样式访问启用绑定检查。

如果array是一个原始指针,那么像array[i]这样的语句在C/C++中可以归结为:

*(array + i)

这是地址+偏移量的简单相加。因此,以下陈述是等效的:

*(array + i), *(i + array), array[i], i[array]

内部发生的情况是,您获取存储在指针中的地址,将数组类型的大小增加i倍,然后取消引用该地址。

因此,如果指定的索引大于数组,则会访问不属于数组的内存。有效地读取了内存中数组旁边的随机数据。如果地址被写入,这是缓冲区溢出的典型来源。如果您试图访问的内存不属于您的进程,您将得到一个segfault。

'a'只是指向内存中(该数组)第一个元素的指针。有些编译器允许您访问内存的其他部分,而不会发出警告。有关阵列的正确使用,请参阅http://www.cplusplus.com/doc/tutorial/arrays/即使用类似的东西

#define MAX 5
int main(){
  int a[MAX];
  for(int i=0;i<MAX;i++){
     a[i]=i;
  }
}