C++ 为什么此代码不显示10^5左右n的输出
我有下面的代码用于计算x^2+ny^2形式的素数,其值不超过N。当N约为80000时,此代码运行正常,但当N约为10^5时,代码会崩溃。为什么会发生这种情况以及如何解决C++ 为什么此代码不显示10^5左右n的输出,c++,C++,我有下面的代码用于计算x^2+ny^2形式的素数,其值不超过N。当N约为80000时,此代码运行正常,但当N约为10^5时,代码会崩溃。为什么会发生这种情况以及如何解决 #include <iostream> #include<iostream> #include<vector> const int N = 100000; //Change N in this line using namespace std; typedef long long int
#include <iostream>
#include<iostream>
#include<vector>
const int N = 100000; //Change N in this line
using namespace std;
typedef long long int ll;
bool isprime[N] = {};
bool zprime[N] = {};
vector<int> primes;
vector<int> zprimes;
void calcprime(){
for (int i = 2; i < N; i+=1){isprime[i] = true;}
for (int i = 2; i < N; i+=1){
if (isprime[i]){
primes.push_back(i);
for (int j = 2; i*j < N; j+=1){
isprime[i*j] = false;
}
}
}
}
void zcalc(){
int sqrt = 0; for (int i = 0; i < N; i+=1){if(i*i >= N){break;} sqrt = i;}
for (int i = 0; i <= sqrt; i +=1){
for (int j = 0; j <= sqrt; j+=1){
ll q = (i*i)+(j*j);
if (isprime[q] && !zprime[q] && (q < N)){
zprimes.push_back(q);
zprime[q] = true;
}
}
}
}
int main(){
calcprime();
zcalc();
cout<<zprimes.size();
return 0;
}
#包括
#包括
#包括
常数N=100000//在这行中更改N
使用名称空间std;
typedef long long int ll;
bool-isprime[N]={};
bool-zprime[N]={};
向量素数;
向量素数;
void calcprome(){
对于(inti=2;i=N){break;}sqrt=i;}
对于(int i=0;i)代码为何中断
越界访问。此代码中断,因为您在这一行执行越界内存访问:
if (isprime[q] && !zprime[q] && (q < N)) {
不建议使用非常大的c数组作为全局变量。这会导致问题并增加可执行文件的大小
(可能)非常大的全局数组。您将isprime
和zprime
定义为c数组:
bool isprime[N] = {};
bool zprime[N] = {};
这可能会导致非常大的N
值出现问题,因为c-array
静态分配内存
如果将isprime
和zprime
更改为向量,则即使N
的值大于1000万,程序也会编译并运行。这是因为使用vector
使分配动态化,堆是存储大量数据的更好地方
std::vector<bool> isprime(N);
std::vector<bool> zprime(N);
q
的值可能超过代码中N
的值,并且在访问zprime[q]
,isprime[q]
时可能会导致分段错误。您正在迭代i
,j
直到sqrt(N)
并已使用N
布尔值分配zprime
,isprime
。q的值可以从0
到2N
不等
ll q = (i*i)+(j*j);
您可以将bool zprime[N]={};
和bool isprime[N]={};
替换为
bool zprime[N * 2 + 1] = {};
及
分别
程序将不再segfault。或者,您可以在访问isprime[q]
和zprime[q]
之前检查q
此外,正如在评论中已经指出的,(i*i)+(j*j)
是一个int
。将该值分配给long
是没有用的。如果您打算防止溢出,请将其替换为((ll)i*i)+(j*j)
P>此外,对于大型数组,您应该更喜欢在堆上分配它。<>代码(i*i)+(j*j)< /C>是int。什么是<代码> sieOf(int)< /C>?在您的平台上?欢迎来到C++。首先要了解的是如何有效地使用标准库容器,而不是用“代码> ISPrime[n]做C样式数组。
。您已经在为某些数组类型结构使用向量。为什么不是全部?
ll q = (i*i)+(j*j);
bool zprime[N * 2 + 1] = {};
bool isprime[N * 2 + 1] = {};