下面是我的代码,用于解决PE的问题7(“找到第10001个素数”):
#include <iostream>
using namespace std;
bool isPrime(int n, int primes[], int l){
int i=0;
for (int i=0; i < l; i++){
if (primes[i] != 0 && n%primes[i] == 0){
return false;
}
}
return true;
}
int main()
{
int k=3;
int primes[10001] = {0};
primes[0]=2;
const int l=sizeof(primes)/sizeof(primes[0]);
int N=0;
while (N < l){
if(isPrime(k, primes, l)==true){
primes[++N]=k;
}
k+=2;
}
cout << primes[l-1] << endl;
return 0;
}
这段代码解决了这个问题,但是它有一个错误:在while
循环的最后一次迭代中,指令是设置primes[10001]=k;
,它试图改变一个元素的值一个不存在的数组。如果我没有声明它是常数,并且(作为一种排除故障的方法)在while循环中将l
替换为10001
,则l
的值将等于第10002个素数在循环结束时。
以下是这种情况的主要功能部分:
int main()
{
int k=3;
int primes[10001] = {0};
primes[0]=2;
int l=sizeof(primes)/sizeof(primes[0]);
int N=0;
while (N < l){
if(isPrime(k, primes, 10001)==true){
primes[++N]=k;
}
k+=2;
}
cout << l << endl;
return 0;
}
我的问题是,为什么会这样?我知道一个简单的解决方法就是停止l-1
的循环(或者更好,用N=1
进行初始化,然后再增加N
),但我对这段代码更感兴趣可以影响一个未明确(直接?)参与代码不良部分的变量。
谢谢!
答案 0 :(得分:2)
[]
运算符不进行边界检查。 some_array[102]
,如果在数组之外,那将简单地变为102 * sizeof(type),那就是数组之外的数据。 C ++不在乎。
如果你很幸运,程序会崩溃,这些是可能产生的一些最糟糕的错误,有时你最终可能会改变其他人的变量。
这就是为什么我在工作中努力使用std::array
和std::vector
,因为它们带有.at(i)
函数,这些函数具有边界检查功能。