数组溢出c++ (at arr[0])
Array overflow c++ (at arr[0])?
昨晚我教了我妹妹一些基本的代码如何读取输入,将其放入数组并打印到屏幕上。下面是代码:
int main() {
int N; // size of array
cin >> N;
int arr[N];
for(int i = 1; i<= N; i++) {
cin >> arr[i];
}
for(int i = 0; i<N; i++) {
cout << arr[i] << endl;
}
return 0;
}
结果如下:
input :
4
2 3 4 1
output :
8
2
3
4
我没有任何线索为什么会发生这种情况,我试着检查代码,但它似乎很简单,对我来说已经正确了。
首先c++不支持变长数组,如果一个数组被声明为有N个元素,那么有效的索引范围是[0, N-1]
。
您可以自己动态分配所需大小的数组,也可以使用标准容器std::vector<int>
。
使用std::vector<int>
,你可以写
#include <iostream>
#include <vector>
int main()
{
unsigned int n = 0;
std::cout << "Enter number of elements: ";
std::cin >> n;
std::vector<int> v( n );
std::cout << "Enter " << n << " elements: ";
for ( int &x : v ) std::cin >> x;
std::cout << "nThe array is ";
for ( int x : v ) std::cout << x << ' ';
std::cout << std::endl;
return 0;
}
程序输出可能看起来像
Enter number of elements: 10
Enter 10 elements: 0 1 2 3 4 5 6 7 8 9
The array is 0 1 2 3 4 5 6 7 8 9
您必须注意的第一件事是dasblinkenlight已经在他的回答中提到,可变长度数组是一种语言扩展。
那么你应该认为数组是基于零索引的。这是什么意思?让我们考虑一个大小为4的数组,表示为arr
。然后它的元素可以作为arr[0]
, arr[1]
, arr[2]
和arr[3]
访问。那么运行第一个循环时会发生什么呢?
for(int i = 1; i<= N; i++) {
cin >> arr[i];
}
设置arr[1]
、arr[2]
的a值为arr[N]
。但是arr[N]
指向内存中与数组无关的位置,因为数组的大小是N,并且所有数组都是从零开始的。数组的最后一个元素在这里arr[n-1]
。
不幸的是,在c++中没有任何对数组长度的检查,你可以这样做。例如,如果你在c#或Java中尝试过这个,那么你就会得到一个索引超出范围的异常。
如果您将代码更改为以下内容,那么您将得到预期的输出:
for(int i = 0; i<N; i++) {
cin >> arr[i];
}
for(int i = 0; i<N; i++) {
cout << arr[i] << endl;
}
你的代码在c++中是无效的,因为可变长度数组是一种语言扩展。
把这部分弄清楚后,考虑一下在第一个循环的最后一步中发生了什么:你访问了数组末尾以外的元素,这是未定义的行为。
你的第二个循环是正确的,所以你所需要做的就是纠正第一个循环的头,使其与第二个循环的头匹配。
N个元素的数组的索引从0到N-1(所以:N-1 - 0 + 1 = N个元素,一些数学)
将for(int i = 1; i<= N; i++)
修改为for(int i = 1; i< N; i++)
- arr[-1]在c++中的奇怪行为
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- "CID"在AT+HTTPPARA= "CID" ,1中是什么意思
- 在C++中用新表达式制作 arr[n][n]
- 在C++中使用 Catch 测试框架编译错误"error: expected ';' at end of declaration list"
- CMake 用于设定C++标准的设施 "at least C++NN"
- SIGSEGV on Boost UDP 套接字关闭 - tcache_get at malloc.c.
- 使用 mat.at<uchar>(i,j) 的 opencv C++中的矩阵赋值错误
- CMake Error at modules/videoio/cmake/detect_ffmpeg.cmake:16
- 当键值是 std 向量时,为什么使用 at in C++ 访问映射值如此缓慢?
- different between int **arr =new int [ n]; and int a[i][j]?
- 两个垫子的 OpenCV 数据是相同的,但使用 Mat::at 检索时的值已损坏
- arr[n] 是否以 C++ 为单位打印数组的长度?
- 为什么存储在数组中的地址值与其自己的地址相同,它应该指向某个不同的地址(&arr[0])?
- C++:' arr '和' arr[] '有什么区别
- 使用 at() 访问 std::map 元素是否比运算符 [] 慢?
- 错误:调用 .. at return 语句时没有匹配函数
- OpenCV 像素访问点与 at() - 不同的值
- 数组溢出c++ (at arr[0])