【发布时间】:2016-11-01 05:50:31
【问题描述】:
我目前正在尝试使用 BitSet 在 C 中实现 Eratosthenes 筛选,但是当我尝试筛选高达 1,000,000(100 万)的素数时出现分段错误 - 100,000(100000)仍在工作不过,我不知道为什么会出现段错误。
这是我使用的代码(我标记了发生错误的行):
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
void eSieve(uint64_t upperLimit);
int main(int argc, char *argv[]) {
uint64_t upperLimit;
if (argc == 2) {
upperLimit = (uint64_t) atoll(argv[1]);
printf("Using custom limit: %" PRIu64 "\n", upperLimit);
} else {
upperLimit = 1000;
printf("Using default limit: %" PRIu64 "\n", upperLimit);
}
eSieve(upperLimit);
return 0;
}
typedef uint32_t prime_t;
void eSieve(uint64_t upperLimit) {
if (upperLimit < 2) {
printf("FAILURE: Bad upper limit.\n");
return;
}
prime_t *sieve = calloc(1, (upperLimit + sizeof(prime_t) - 1)/sizeof(prime_t));
if (!sieve) {
printf("FAILURE: Could not initialize sieve.\n");
return;
}
sieve[0] |= 3; // Set first and second bit (representing 0 and 1)
uint64_t prime, number;
for (prime = 2; prime * prime < upperLimit; ) {
for (number = prime * prime; number < upperLimit; number += prime) {
// Segmentation fault for prime = 2 and number = 258048
sieve[number/sizeof(prime_t)] |= (((prime_t) 1) << (number % sizeof(prime_t)));
}
while ((sieve[++prime/sizeof(prime_t)] & (prime_t)1 << (prime % sizeof(prime_t))) != 0)
;
}
number = upperLimit;
while ((sieve[--number/sizeof(prime_t)] & (((prime_t)1) << (number % sizeof(prime_t)))) != 0)
;
printf("Greatest prime-number below %" PRIu64 ": %" PRIu64 "\n",
upperLimit, number);
}
有人知道错误发生的原因吗?我猜现在分配了足够的空间(不知何故),但我现在看不出这怎么可能......
【问题讨论】:
-
在您的代码中哪里获得 SIGSEGV?
-
@AndrewHenle 我写了一条评论。
-
您说您使用的是 bit 数组,但实际上您似乎使用的是 byte 数组。可能是。您的代码有点难以理解。如果您确实打算使用位数组,那么最好将您的测试和设置操作分解为宏。
-
prime * prime显然是比upperLimit更大的值,就这么简单?使用调试器并检查。 -
我打赌
prime * prime会溢出 64 位。
标签: c segmentation-fault dynamic-memory-allocation bit-fields sieve-of-eratosthenes