简体   繁体   English

“试图接收信号SIGSEGV,分段错误”尝试使用递归获取3个字符组合的所有关键字时

[英]"Program received signal SIGSEGV , Segmentation fault” When trying to get all keywords of 3-character combinations using recursion

I am trying to get all keywords of 3 characters using recursion but after some calls maybe call stack is full and the program crash with segmentation fault error , Code : 我试图使用递归获取所有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); 
}

How deep do you expect your recursion to run? 您期望递归进行多深?

You will get 52 levels iterating the last character from 'A... Za...z', 52*52 levels iterating over the last two characters, and 52*52*52 total recursion depth. 您将获得52个级别,从“ A ... Za ... z”迭代最后一个字符,在最后两个字符上迭代的52 * 52个级别,以及52 * 52 * 52的总递归深度。

That's a recursion that is 140608 levels deep. 这是深度140608级别的递归。

Every time you call a routine, you use some amount of stack. 每次调用例程时,都会使用一定数量的堆栈。 A return address must be saved. 寄信人地址必须保存。 Often some registers must be saved as well. 通常,某些寄存器也必须保存。

On a 64-bit system, without optimization, it is likely that at least 32 bytes of stack will be used for each recursion level. 在没有优化的64位系统上, 每个递归级别可能至少使用32个字节的堆栈。 That's 4499456 bytes. 那是4499456字节。 The stack limit on Linux is often 8MB, so you shouldn't run out of stack (and your program does not crash for me in either 64 or 32-bit mode). Linux上的堆栈限制通常为8MB,因此您不应该用完堆栈(在64位或32位模式下程序不会对我造成崩溃)。 But you'll be using more than half of your available stack. 但是您将使用超过一半的可用堆栈。

Your system probably has a lower stack limit (perhaps 4MB). 您的系统可能具有较低的堆栈限制(可能为4MB)。 If so, your program will run out of stack. 如果是这样,您的程序耗尽堆栈。

On Linux (and other UNIX OSes), use ulimit -s to find out what your current stack limit is, and ulimit -s unlimited to remove the stack limit (this should also allow your program to run to completion without hitting SIGSEGV ). 在Linux(和其他UNIX操作系统)上,使用ulimit -s找出当前的堆栈限制,并使用ulimit -s unlimited删除堆栈限制(这也应使您的程序运行至完成而无需点击SIGSEGV )。

PS Using recursion for this trivially iterable problem is ill -advised, precisely because you will use a lot of stack space. PS对这个琐碎的迭代问题使用递归是不明智的 ,这恰恰是因为您将使用大量的堆栈空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM