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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了“程序收到信号SIGSEGV,分段错误”当试图使用递归获取3个字符组合的所有关键字时相关的知识,希望对你有一定的参考价值。

我试图使用递归获取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的情况下运行完成)。

附:对于这个简单的可迭代问题使用递归是不明智的,正是因为你将使用大量的堆栈空间。

以上是关于“程序收到信号SIGSEGV,分段错误”当试图使用递归获取3个字符组合的所有关键字时的主要内容,如果未能解决你的问题,请参考以下文章

执行动态 malloc 代码时出现“分段错误”

是否可以用 C++ 为 X11 Xlib 编程而不是使用 C?

如何乘以和除以一天中的时间,例如10:00 和 5:00 具有重载功能?

使用 Valgrind 工具如何检测尝试访问 0x0 地址的对象?

当作者试图进入写锁时如何避免阻塞 ReaderWriterLockSlim 读者

c++ 。我试图通过在开关内使用数组来获取用户输入,但是当我运行代码时它显示分段错误?