“程序收到信号 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 层深的递归。
每次调用例程时,都会使用一些堆栈。必须保存 return 地址。通常还需要保存一些寄存器。
在 64 位系统上,如果不进行优化,很可能至少 32 字节的堆栈将用于 每个 递归级别。那是 4499456 字节。 Linux 的堆栈限制通常为 8MB,因此您不应该 运行 超出堆栈(并且您的程序在 64 位或 32 位模式下都不会崩溃)。但是您将使用超过一半的可用堆栈。
您的系统可能有较低的堆栈限制(可能是 4MB)。如果是这样,您的程序 将 运行 出栈。
在 Linux(和其他 UNIX 操作系统)上,使用 ulimit -s
找出您当前的堆栈限制,然后使用 ulimit -s unlimited
删除堆栈限制(这也应该允许你的程序 运行 完成而没有命中 SIGSEGV
)。
P.S。 ill 建议使用递归解决这个简单的可迭代问题,正是因为您将使用 lot 的堆栈 space.
我正在尝试使用递归获取所有 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 层深的递归。
每次调用例程时,都会使用一些堆栈。必须保存 return 地址。通常还需要保存一些寄存器。
在 64 位系统上,如果不进行优化,很可能至少 32 字节的堆栈将用于 每个 递归级别。那是 4499456 字节。 Linux 的堆栈限制通常为 8MB,因此您不应该 运行 超出堆栈(并且您的程序在 64 位或 32 位模式下都不会崩溃)。但是您将使用超过一半的可用堆栈。
您的系统可能有较低的堆栈限制(可能是 4MB)。如果是这样,您的程序 将 运行 出栈。
在 Linux(和其他 UNIX 操作系统)上,使用 ulimit -s
找出您当前的堆栈限制,然后使用 ulimit -s unlimited
删除堆栈限制(这也应该允许你的程序 运行 完成而没有命中 SIGSEGV
)。
P.S。 ill 建议使用递归解决这个简单的可迭代问题,正是因为您将使用 lot 的堆栈 space.