c - "Program received signal SIGSEGV , Segmentation fault” 尝试使用递归获取所有3字符组合的关键字时

标签 c recursion segmentation-fault cs50

我正在尝试使用递归获取 3 个字符的所有关键字,但在一些调用之后可能调用堆栈已满并且程序因段错误而崩溃,代码:

#include <cs50.h>
#include <stdio.h>

void three_Characters(char c, char c2, char c3);

int main(void){
    three_Characters('A', 'A', 'A');
    return 0;
}

void three_Characters(char c, char c2, char c3){

//print 3-characters 
    printf("%c%c%c - ", c, c2, c3);

    /*Recursion termination*/
    if(c == 'z' && c2 == 'z' && c3 == 'z'){
        return;
    }

    /*Avoid symbol characters */
    if(c3 == 'Z'){
        c3 += 6;
        if(c2 == 'Z'){
            c2 += 7;
            if(c == 'Z'){
            c += 7;
            }
        }
    }

    if(c3 == 'z'){
        if(c2 == 'z'){
            c += 1;   c2 = 65;   c3 = 64;
        }else{
            c2 += 1;  c3 = 64;
        }
    }
    three_Characters(c, c2, c3 + 1); 
}

最佳答案

您希望递归运行多深?

您将获得 52 级迭代“A...Za...z”中的最后一个字符,52*52 级迭代最后两个字符,以及 52*52*52 的总递归深度。

这是一个 140608 层深的递归。

每次调用例程时,都会使用一定数量的堆栈。必须保存回邮地址。通常还必须保存一些寄存器。

在 64 位系统上,如果不进行优化,很可能至少 32 字节的堆栈将用于每个 递归级别。那是 4499456 字节。 Linux 上的堆栈限制通常为 8MB,因此您不应用完堆栈(并且您的程序在 64 位或 32 位模式下都不会崩溃)。但是您将使用一半以上的可用堆栈。

您的系统可能有较低的堆栈限制(可能是 4MB)。如果是这样,您的程序用完堆栈。

在 Linux(和其他 UNIX 操作系统)上,使用 ulimit -s 找出您当前的堆栈限制,然后使用 ulimit -s unlimited 删除堆栈限制(这也应该允许您的程序运行完成而无需点击 SIGSEGV)。

附言对这个简单的可迭代问题使用递归是不明智的建议,正是因为您将使用很多堆栈空间。

关于c - "Program received signal SIGSEGV , Segmentation fault” 尝试使用递归获取所有3字符组合的关键字时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52103830/

相关文章:

c - 随机数数组。 C

c - 为什么 sizeof(array) 和 sizeof(&array[0]) 给出不同的结果?

c++ - 如何使用递归计算字符串中的元音

c++ - 双端队列错误

ios - 苹果因启动崩溃而拒绝应用程序

c - 太多打开的文件c

c - 为什么 C 语言中的 free() 不起作用?

javascript - 在 JavaScript 中递归生成行分组

memory - Haskell 递归和内存使用

segmentation-fault - 向右旋转和向右疯狂操作会引发段错误