C++ 为什么一个大的数字输入会为这个代码生成一个运行时错误来计算primeCounting?
任务是计算输入参数N以下的素数。 我正在用从小到大的不同输入数测试这段代码。非常奇怪,我只在输入值大于等于46342时遇到运行时错误。如果输入值小于46342,则代码运行良好,没有任何运行时错误C++ 为什么一个大的数字输入会为这个代码生成一个运行时错误来计算primeCounting?,c++,c++11,count,runtime-error,primes,C++,C++11,Count,Runtime Error,Primes,任务是计算输入参数N以下的素数。 我正在用从小到大的不同输入数测试这段代码。非常奇怪,我只在输入值大于等于46342时遇到运行时错误。如果输入值小于46342,则代码运行良好,没有任何运行时错误 int countPrimes(int n) { if (n <= 2) return 0; vector<bool> array(n,true); int cnt = 0; for (int i = 2 ; i < n ; i++) {
int countPrimes(int n) {
if (n <= 2) return 0;
vector<bool> array(n,true);
int cnt = 0;
for (int i = 2 ; i < n ; i++)
{
for (int j = i ; i * j < n ; j++)
{
int product = i * j;
if (array[product])
{
array[product] = false;
cnt++;
}
}
}
return n - 2 - cnt;
}
int countPrimes(int n){
如果(n1),则:
将溢出,使产品
等于负数
然后,您将尝试使用负索引访问array
(实际上是一个向量,因此将其命名为array
不是一个好的选择),这将导致程序崩溃
您需要使用能够支持更大数值的类型。现在您使用了int
()。对于n
、i
、j
、以及product
,
int product = i * j;
将溢出,使产品
等于负数
然后,您将尝试使用负索引访问array
(实际上是一个向量,因此将其命名为array
不是一个好的选择),这将导致程序崩溃
您需要使用能够支持更大数值的类型。现在您使用了int
()。对于n
、i
、j
、和product
使用int
的最大值是2的31次方,等于2147483648。
这个值的平方根是46340.95,因此您正在使用的值(通过执行i*j
)超过该限制,导致运行时异常。int
的最大值是2的31次方,等于2147483648。
这个值的平方根是46340.95,因此您正在使用的值(通过执行i*j
)超过该限制,导致运行时异常。如其他答案中所述,OP遇到的是两个问题的组合,整数溢出和向量的越界访问,这两个问题都是未定义行为的原因
线路
int product = i * j;
声明一个int
变量,该变量初始化为i
和j
的乘积,其类型为int
,引用
如果不存在长度修饰符,则保证其宽度至少为16位。然而,在32/64位系统上,几乎完全保证其宽度至少为32位
显然,在OP的系统中,int
具有32位宽度,因此大于46341的i
值使操作46342*46342=2147580964溢出可表示数字的范围(int_MAX可能是2147483647)
在溢出的情况下,行为是未定义的,但在大多数体系结构中,整数以2的补码表示,可以获得负数,这导致未定义行为的另一个原因,可能是问题中提到的“运行时错误”:
if (array[product]) // <- 'product' can be negative
// 'array.at(product)' would have caught this error
{
array[product] = false;
//…
if(array[product])/如其他答案所述,OP遇到的是两个问题的组合,整数溢出和向量越界访问,这两个问题都是导致未定义行为的原因
线路
int product = i * j;
声明一个int
变量,该变量初始化为i
和j
的乘积,其类型为int
,引用
如果不存在长度修饰符,则保证其宽度至少为16位。然而,在32/64位系统上,几乎完全保证其宽度至少为32位
显然,在OP的系统中,int
具有32位宽度,因此大于46341的i
值使操作46342*46342=2147580964溢出可表示数字的范围(int_MAX可能是2147483647)
在溢出的情况下,行为是未定义的,但在大多数体系结构中,整数以2的补码表示,可以获得负数,这导致未定义行为的另一个原因,可能是问题中提到的“运行时错误”:
if (array[product]) // <- 'product' can be negative
// 'array.at(product)' would have caught this error
{
array[product] = false;
//…
if(array[product])//您可以简单地打印出product
的值来查看错误。您可以简单地打印出product
的值来查看错误。感谢您的帮助。我在循环条件中考虑了(int j=I;I*ji*j
overflows@newbie,所以您试图计算以保护它的表达式也有错误。您必须使用更大的数据类型,例如unsigned int
,或long int
。我明白了。非常感谢,这确实解决了我的问题m、 欢迎您@newbie。欢迎来到Stack Overflow,您发布了一个很好的第一个问题,这就是我投票给您的原因。别忘了接受这里发布的答案。感谢您的帮助。我在循环条件中考虑了(int j=I;I*ji*j
overflows@newbie,所以您试图计算以保护它的表达式也有错误。您必须使用更大的数据类型,例如unsigned int
,或long int
。我明白了。非常感谢,这确实解决了我的问题m、 欢迎@newbie。欢迎来到Stack Overflow,你发布了一个很好的第一个问题,这就是为什么我投票给你。别忘了接受这里发布的答案。非常感谢各位,上面的答案确实解决了我的问题。我非常感谢。非常感谢各位,上面的答案确实解决了我的问题。我非常感谢1.非常感谢鲍勃的详细解释非常感谢鲍勃的详细解释