c - C 段错误中的大型阵列,erathos 的 Sievs

标签 c memory stack

所以,我已经得到了这段代码。

void main(void){

    int n = 9999;
    int *array = calloc(n, sizeof(int));
    int i, j;

    // Populate array up to N
    for(i = 0; i < n; i++){
        array[i] = 2 + i;
    }

    // Run sievs
    sievs(array, n);

    print_prime(array, n);
}

我的问题是,如果 N 足够大,程序将进行核心转储。我的理论是,有些东西是在堆栈上分配的,而且它不够大,无法容纳那么多数据,但是我使用的是 calloc,所以它应该在堆上。

两个打印函数看起来像这样:

void print_prime(int *a, int n){
    int i;
    for (i = 0; i < n; i++){
        if(a[i] != -1)
            printf("Prime: %d \n", a[i]);
    }
}

是否有任何代码导致此问题?我不明白为什么。

这是 siev 函数:

void sievs(int *array, int n){

    int i, j;

    for(i = 2; i <= n; i++){
        if(array[i-2] != -1){
            for(j = i*i; j <= n; j+=i){
                array[j-2] = -1;
            }
        }
    }

}

我看不出有什么问题,但是,我只是计算机科学专业的第二年,所以我在 C 方面没有那么丰富的经验。我已经尝试解决这个问题一段时间了。对于小数字来说它工作得很好。然而,对于大型的情况并非如此,我在互联网上读到的所有内容都表明这可能是堆栈的问题。

这里有什么东西被分配在堆栈上吗?

最佳答案

程序将在 n 足够大时崩溃,因为

j = i * i

将导致j变量(int类型)溢出。因此在

array[j-2] = -1;

索引j - 2将为负数。

您可以通过声明 j 至少为 long 或借助任意精度库(例如 the GNU Multiple Precision Arithmetic Library )来解决该问题。

关于c - C 段错误中的大型阵列,erathos 的 Sievs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25745194/

相关文章:

c - "*** stack smashing detected ***"带文件读写

java - android中的MemoryFile有什么用

architecture - 为什么堆栈通常向下增长?

c# - 列表/树/堆栈 - 算法

c - 在 C 中使用 LVM_GETITEM 和 SendMessage 获取 LVITEM 的文本

c - 在 if/else block 中跟踪具有多个分支的程序

c - 当我尝试将函数的参数设置为默认时发生意外错误

c - valgrind 错误 : invalid read

amazon-web-services - AWS Lambda 函数需要的内存超过 CloudWatch 中报告的最大内存

c - 为什么我需要设置比实际大小更大的堆栈大小?