我找不到内存泄漏。 (SIGSEGV)(Eratosthenes的分段筛)(C)

时间:2014-10-17 00:14:29

标签: c memory-leaks sieve-of-eratosthenes

我试图在C(初学者程序员)中实现Eratosthenes的分段筛,它只打印正确的输出,但是当我在SPOJ上提交时,我得到了SIGSEGV。你能帮我发现泄漏吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

void segmented_sieve(int *m, int *n, int t) {
int count, i, j, l, sqrt_imax, hlp_imin;
count = i = j = l = sqrt_imax = hlp_imin = 0;
int *imin, *imax;
imin = m;
imax = n;
sqrt_imax = (int)sqrt((double)imax[t]);
int *sieve;
sieve = malloc((imax[t] + 1) * sizeof(*sieve));
memset(sieve, 1, (imax[t] + 1) * sizeof(*sieve));
for (i = 2; i <= sqrt_imax; ++i) {
    for (j = i * i; j <= imax[t]; j += i)
        sieve[j] = 0;
}
int *next;
next = malloc((int)sqrt(1000000000) * sizeof(*next));
for (i = 2; i <= sqrt_imax; ++i) {
        if (sieve[i] > 0) {
                ++count;
                next[count] = i;
        }
}
for (i = 1; i <= count; ++i) {
    if (imin[t] <= 2) {
        imin[t] = 2;
        for (j = next[i]; j <= sqrt_imax; j = next[i]) {
            for (l = j * j; l <= n[t]; l += j)
                sieve[l] = 0;
            break;
        }
    }
    else {
        hlp_imin = (int)(m[t] / next[i]);
        hlp_imin *= next[i];
        for (j = next[i]; j <= sqrt_imax; j = next[i]) {
                for (l = hlp_imin; l <= imax[t]; l += j)
                        sieve[l] = 0;
                break;
        }
    }
}
for (i = imin[t]; i < imax[t]; ++i)
    sieve[i] > 0 ? printf("%d\n", i) : 0;
free(sieve);
free(next);
}

int main()
{
int t, tmp, i;
t = tmp = i = 0;
scanf("%d", &t);
int *m;
m = malloc(t * sizeof(*m));
int *n;
n = malloc(t * sizeof(*n));
for (i = 0; i < t; ++i) {
    scanf("%d", &tmp);
    m[i] = tmp;
    scanf("%d", &tmp);
    n[i] = tmp;
}
for (i = 0; i < t; ++i) {
    segmented_sieve(m, n, i);
    printf("\n");
}
free(m);
free(n);
return 0;
}

我通过将int更改为char来修复它。现在刚刚获得TLE ......

1 个答案:

答案 0 :(得分:1)

想想如果你得到两个值imin = 2,000,000,000和imax = 2,000,000,010会发生什么。你应该只为11个数字创建一个小筛子。但是,您可以分配20亿个整数的存储空间,这可能超过您的计算机所能处理的数量。