提问人:Simon Klyvare 提问时间:12/20/2022 最后编辑:wohlstadSimon Klyvare 更新时间:12/20/2022 访问量:97
如何在 C 中制作一个有很多位置的数组?
how do i make a array with lots of places in c?
问:
我正在制作 c 中 erasthostenes 的筛子。我以前用其他语言编程过,但我从未遇到过这个问题。这是我的算法:
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
#include <time.h>
#include <limits.h>
int main(){
clock_t t;
t = clock();
int n = 1299710;
bool pPrimes[n];
for(int i = 0; i<n; i++){
pPrimes[i] = true;
}
pPrimes[0] = false;
pPrimes[1] = false;
for(int i = 2; i<sqrt(n); i++){
if(pPrimes[i]){
for(int x = i*i; x<n; x+=i){
pPrimes[x] = false;
}
}
}
for(int i = 2; i<n; i++){
if (pPrimes[i]){
printf("%d\n", i);
}
}
t = clock() - t;
double time_taken = ((double)t)/CLOCKS_PER_SEC;
printf("%f", time_taken);
return 0;
}
这是我宣布这还不够大的时候。大约有一百万个工作,但不会更多。有没有办法解决这个问题?pPrimes
n
我尝试调试,但我只收到以下错误消息:
第 1 行:4320 分段故障:11
答:
0赞
chux - Reinstate Monica
12/20/2022
#1
一些问题:
本地空间不足
OP报告大,有麻烦。最好使用 .n
malloc()
bool
肯定不是最窄的类型 - 使用 .最好使用无符号大小(如 或 )进行分配。unsigned char
unsigned
size_t
//int n = 1299710;
//bool pPrimes[n];
unsigned n = 1299710;
if (n < 2) { // Avoid edge cases
fprintf(stderr, "Use larger value, not %u\n", n);
return EXIT_FAILURE;
}
unsigned char *pPrimes = malloc(sizeof *nPrimes * n);
if (pPrimes == NULL) {
fprintf(stderr, "Out-of-memory %u\n", n);
return EXIT_FAILURE;
}
相差一
我希望暗示找到所有素数,包括 .int n = 1299710;
n
unsigned char *pPrimes = malloc(sizeof *nPrimes * (n+1));
// for(int i = 2; i<n; i++){
for(unsigned i = 2; i <= n; i++){ // <=
引用此伪代码,边缘测试将关闭 1。
不要相信原始数据的整数问题。当预期结果为 x.00000...时,该函数可能会返回 x_minus_1.99999...。sqrt()
unsigned qsrt_n = lround(sqrt(n));
// for(int i = 2; i<sqrt(n); i++){
for(unsigned i = 2; i <= sqrt_n; i++){ // <=
if(pPrimes[i]){
// for(int x = i*i; x<n; x+=i){
for(unsigned x = i*i; x <= n; x+=i){ // <=
pPrimes[x] = false;
}
}
}
0赞
Zakk
12/20/2022
#2
您在堆栈中分配了过多的内存。这称为堆栈溢出。
要么(正如@Gerhardh在评论中所说):
- 使用数组
static
- 使用全局数组
- 用
malloc()
1. 使用数组:static
int main(void)
{
#define n 1299710
static bool primes[n] = {false, false};
for (size_t i = 2; i < n; ++i) {
primes[i] = true;
}
long srn = sqrt(n) + 1;
for (size_t i = 0; i < srn; ++i) {
if (!primes[i]) continue;
for (size_t ii = i*i; ii < n; ii += i)
primes[ii] = false;
}
// print...
}
2. 使用全局数组:
#define n 1299710
/*static?*/ bool primes[n] = {false, false};
int main(void)
{
for (size_t i = 2; i < n; ++i) {
primes[i] = true;
}
long srn = sqrt(n) + 1;
for (size_t i = 0; i < srn; ++i) {
if (!primes[i]) continue;
for (size_t ii = i*i; ii < n; ii += i)
primes[ii] = false;
}
// print...
}
3. 使用动态数组:
int main(void)
{
const size_t n = 1299710;
bool *primes = malloc(n * sizeof bool);
if (!primes) {
printf("Memory issues. Goodbye!\n");
return EXIT_FAILURE;
}
for (size_t i = 2; i < n; ++i) {
primes[i] = true;
}
primes[0] = false;
primes[1] = false;
long srn = n == 1 ? 1 : sqrt(n) + 1;
for (size_t i = 0; i < srn; ++i) {
if (!primes[i]) continue;
for (size_t ii = i*i; ii < n; ii += i)
primes[ii] = false;
}
// print...
}
评论
1赞
Zakk
12/20/2022
@chux-ReinstateMonica 也许强制执行是要走的路,因为整个算法对 .n > 2
n <= 1
0赞
chux - Reinstate Monica
12/20/2022
某些看起来仍然不对劲。我期待.for (size_t i = 0; i < srn; ++i) {
for (size_t i = 0; i <= srn; ++i) {
评论
bool pPrimes[n];
static bool pPrimes[SIZE];
SIZE
#define SIZE 1299710
n
n