尽管在堆上分配内存,但仍出现 SISGEV 错误? (生成素数)
SISGEV error despite allocating memory on heap? (generating primes)
作为竞争性编程,我编写了代码来生成范围 (使用修改后的埃拉托色尼筛法) 内的素数。该代码在我的 Visual Studio 上运行良好,但在网站上给出了一个 SISGEV。我用这个,
static bool *prime = new bool[1000000001];
声明内存。并且无法理解SISGEV背后的原因。
下面是函数,参数为the lower limit m
和the upper limit n
。
索引 >m
中不是质数 的元素标记为 false。
static bool *prime = new bool[1000000009];
void SieveOfEratosthenes(int m, int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
memset(prime, true, n + 11);
int m2;
if (m > 10) {
m2 = m / 10;
m2 = m2 * 10;
m2 = (2 * m2) / 5;
}
else
m2 = 4;
prime[1] = false;
prime[2] = true;
prime[3] = true;
prime[5] = true;
for (int i = m2; i <= n; i += 2) {
if ( (5*2)/2 >= n) break;
prime[i] = false;
prime[(3 * i) / 2] = false;
prime[(5 * i) / 2] = false;
}
int m3;
m3 = m % 7;
m3 = m - m3;
for (int p = 7; (p)*(p) <= n; p += 6) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true) {
// Update all multiples of p,
for (int i = p; i <= n; i += p) {
prime[m3+i] = false; //cout << i << " ";
if (prime[m3 + p+ 4]) prime[((p+4)*i)/p] = false;
if (prime[m3 + p + 6]) prime[((p+6)*i)/p] = false;
}
}
prime[7] = true;
prime[11] = true;
prime[13] = true;
}
// Print all prime numbers
for (int p = m; p <= n; p++)
if (prime[p])
cout << p << endl;
}
int main() {
//other code
delete[] prime;
}
你的指针是一个静态变量。在 C++ 中,静态变量的初始化只发生一次。但是,delete[]
语句会在每次函数调用时执行。
不要在风车上倾斜并使用std::vector
而不是滚动raw-memory解决方案。
使用 std::vector
的简单实现:(添加扩展功能留作 reader 的练习。)
#include <vector>
#include <cmath>
#include <cstddef>
#include <algorithm>
#include <iostream>
std::vector<std::size_t> eratosthenes(std::size_t const n)
{
std::vector<bool> A(n, true);
std::vector<std::size_t> r;
auto const limit = static_cast<std::size_t>(
std::ceil(std::sqrt(static_cast<double>(n))));
// check all numbers up to sqrt(n)
for (std::size_t i = 2; i <= limit; ++i)
{
// if i is prime,
if (A[i])
{
// i is prime, put it into return vector
r.push_back(i);
// set all multiples of i (below n) to false
for (std::size_t j = i*i; j < n; j+=i)
{
A[j] = false;
}
}
}
// fill rest of the primes > sqrt(n) into r
if (!r.empty())
{
for (auto i = limit+1u; i < n; ++i)
{
if (A[i]) r.push_back(i);
}
}
return r;
}
正在打印:
int main()
{
for (auto v : eratosthenes(120))
{
std::cout << v << "\n";
}
return 0;
}
作为竞争性编程,我编写了代码来生成范围 (使用修改后的埃拉托色尼筛法) 内的素数。该代码在我的 Visual Studio 上运行良好,但在网站上给出了一个 SISGEV。我用这个,
static bool *prime = new bool[1000000001];
声明内存。并且无法理解SISGEV背后的原因。
下面是函数,参数为the lower limit m
和the upper limit n
。
索引 >m
中不是质数 的元素标记为 false。
static bool *prime = new bool[1000000009];
void SieveOfEratosthenes(int m, int n)
{
// Create a boolean array "prime[0..n]" and initialize
// all entries it as true. A value in prime[i] will
// finally be false if i is Not a prime, else true.
memset(prime, true, n + 11);
int m2;
if (m > 10) {
m2 = m / 10;
m2 = m2 * 10;
m2 = (2 * m2) / 5;
}
else
m2 = 4;
prime[1] = false;
prime[2] = true;
prime[3] = true;
prime[5] = true;
for (int i = m2; i <= n; i += 2) {
if ( (5*2)/2 >= n) break;
prime[i] = false;
prime[(3 * i) / 2] = false;
prime[(5 * i) / 2] = false;
}
int m3;
m3 = m % 7;
m3 = m - m3;
for (int p = 7; (p)*(p) <= n; p += 6) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true) {
// Update all multiples of p,
for (int i = p; i <= n; i += p) {
prime[m3+i] = false; //cout << i << " ";
if (prime[m3 + p+ 4]) prime[((p+4)*i)/p] = false;
if (prime[m3 + p + 6]) prime[((p+6)*i)/p] = false;
}
}
prime[7] = true;
prime[11] = true;
prime[13] = true;
}
// Print all prime numbers
for (int p = m; p <= n; p++)
if (prime[p])
cout << p << endl;
}
int main() {
//other code
delete[] prime;
}
你的指针是一个静态变量。在 C++ 中,静态变量的初始化只发生一次。但是,
delete[]
语句会在每次函数调用时执行。不要在风车上倾斜并使用
std::vector
而不是滚动raw-memory解决方案。
使用 std::vector
的简单实现:(添加扩展功能留作 reader 的练习。)
#include <vector>
#include <cmath>
#include <cstddef>
#include <algorithm>
#include <iostream>
std::vector<std::size_t> eratosthenes(std::size_t const n)
{
std::vector<bool> A(n, true);
std::vector<std::size_t> r;
auto const limit = static_cast<std::size_t>(
std::ceil(std::sqrt(static_cast<double>(n))));
// check all numbers up to sqrt(n)
for (std::size_t i = 2; i <= limit; ++i)
{
// if i is prime,
if (A[i])
{
// i is prime, put it into return vector
r.push_back(i);
// set all multiples of i (below n) to false
for (std::size_t j = i*i; j < n; j+=i)
{
A[j] = false;
}
}
}
// fill rest of the primes > sqrt(n) into r
if (!r.empty())
{
for (auto i = limit+1u; i < n; ++i)
{
if (A[i]) r.push_back(i);
}
}
return r;
}
正在打印:
int main()
{
for (auto v : eratosthenes(120))
{
std::cout << v << "\n";
}
return 0;
}