C质数在64901时崩溃 #包括 #包括 #定义大小20000000 int prim[大小]; int i、扎尔、扎勒、erg; 内筛(内筛,内筛[],内筛){ 如果(zahl==2000000) 返回1; 对于(i=0;i

C质数在64901时崩溃 #包括 #包括 #定义大小20000000 int prim[大小]; int i、扎尔、扎勒、erg; 内筛(内筛,内筛[],内筛){ 如果(zahl==2000000) 返回1; 对于(i=0;i,c,function,recursion,C,Function,Recursion,具有讽刺意味的是,这实际上是由于递归导致的堆栈溢出。您可以使堆栈变大(这只会延迟问题),或者从递归解决方案更改为迭代解决方案 (值得一提的是,在这种情况下,一些调试器将无法帮助您。C语言初学者在第一次遇到这个问题之前很难理解到底出了什么问题。恭喜!您在C语言中升级了) 验证它是否确实是堆栈溢出的一种廉价方法是在递归函数中的堆栈上创建额外内存,并查看它崩溃的数字是否从64901变为64901。我的猜测是,如果将likechar dummy[2048]在那里,它会崩溃得更快。我们会这么做。这是一个绝

具有讽刺意味的是,这实际上是由于递归导致的堆栈溢出。您可以使堆栈变大(这只会延迟问题),或者从递归解决方案更改为迭代解决方案

(值得一提的是,在这种情况下,一些调试器将无法帮助您。C语言初学者在第一次遇到这个问题之前很难理解到底出了什么问题。恭喜!您在C语言中升级了)


验证它是否确实是堆栈溢出的一种廉价方法是在递归函数中的堆栈上创建额外内存,并查看它崩溃的数字是否从64901变为64901。我的猜测是,如果将like
char dummy[2048]
在那里,它会崩溃得更快。

我们会这么做。这是一个绝佳的机会,让你学会如何调试自己的程序。你会从中学到比其他人发现你的错误更多的东西。“它总是在64901这个数字上崩溃”并不能用来描述你看到的错误。它是否说“错误#某某”?“分段错误”?它会像成功运行一样停止吗?等等。如果堆栈大小为1MB,则在递归次数达到该数目后,将触底。“压碎”->“崩溃”。)正如Bo所建议的,我怀疑您已经用完了堆栈。对于
sieve
,非递归方法会更好。递归可能很方便,有时可能更透明,但如果不小心管理,它有其严重的缺点。如果您使用Linux,比如说,您可以使用
valgrind
来调试程序中的内存问题。
valgrind./myprogram
。在优化过程中,编译器可能会删除未使用的数组,例如
char dummy[2048]
。可能建议关闭优化,运行程序以建立基线,然后插入虚拟空间并重新运行程序。@ericppostshil或干脆
strcpy()
在一些随机数据中。@匿名选择:试图在这些方面胜过编译器是一件棘手的事情。即使您使用
strcpy
将一些数据复制到
dummy
中,编译器也可以看到它没有被使用,并删除
dummy
strcpy
,因为它们没有明显的效果(如C标准中所定义)。但是,如果您将
dummy
声明为
volatile char dummy[2048]
,然后您可以使用
memset
简单地向其写入零,编译器将被要求实际执行写入操作。请注意那些超级智能编译器,它们会认为您的整个项目毫无意义,并对整个项目进行优化/s@TinyTheBrontosaurus:你是个孩子,但在某些情况下,你确实需要提防exa确实如此。如果你的程序没有可观察的行为,你可能合法地只能得到一个空的
main
#include <stdio.h>
#include <stdlib.h>
#define size 20000000

int prim[size];
int  i, zahl, zaehler, erg;


int sieve(int zahl, int prim[], int zaehler) {
    if(zahl == 2000000)
        return 1;

    for(i=0; i<=zaehler; i++) {
        erg = zahl%prim[i];

        if(erg==0) {
            zahl++;
            return sieve(zahl, prim, zaehler);
        }   
    }           

    zaehler++;
    prim[zaehler]=zahl;
    zahl++;
    printf("%d\n", prim[zaehler]);
    return sieve(zahl, prim, zaehler);      
}

int main(){

    zaehler = 0;
    zahl = 2;       

    for(i=0;i<size;i++)
        prim[i]=2;

    sieve(zahl, prim, zaehler);
}