簡體   English   中英

“試圖接收信號SIGSEGV,分段錯誤”嘗試使用遞歸獲取3個字符組合的所有關鍵字時

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

我試圖使用遞歸獲取所有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 )。

PS對這個瑣碎的迭代問題使用遞歸是不明智的 ,這恰恰是因為您將使用大量的堆棧空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM