尝试递增字母时出现分段错误
Segmentation Fault when trying to increment letters
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <crypt.h>
int main(int argc, string argv[])
{
if(argc > 2){ printf("too many arguments\n"); return 51; }
if(argc < 2){ printf("too few arguments\n"); return 50; }
if(strlen(argv[1]) > 4){ printf("Password is greater than 4 characters\n"); return 52; }
if(argc == 2) //make sure there are enough args
{
string hash_guess = "A";
while(crypt(hash_guess, "50") != argv[1]) //while answer not correct
{
while(hash_guess[0] <= 'Z' && hash_guess[0] >= 'A')
{
hash_guess[0] = hash_guess[0] + 1;
printf("%s", hash_guess);
}
}
}
}
我试图通过一个单词逐个字母递增,所以它会先是 a,然后是 b,然后是 c,直到 z,然后它会变成 aa、ab、ac、ad....然后是 ba bb bc bd .. . 然后 za...zz...zzz。我从一个字母开始,但出现错误 "segmentation fault"
我很惊讶你遇到段错误。您显示的代码甚至不应该编译。
行:
string hash_guess = "A";
使用 string
作为类型。除非您在未显示的部分代码中使用了 typedef string
,否则它不能用于创建变量。
尝试:
char hash_guess[] = "A";//creates array of char, 2 bytes long: |A|0|
即便如此,如果您需要此变量包含超过 2 个字节,请使用更多 space:
创建它
char hash_guess[10] = "A"; Creates space for 10 bytes: |A|0|0|0|0|0|0|0|0|0|
请记住,C 字符串被定义为以 NULL 结尾的字符数组。
编辑 根据@MichaelDorgan 的发现,cs50
typedefs String
as char *
。所以违规行现在等同于:
char *hash_guess = "A";
这就是它编译和运行的原因。当您明确尝试写入内存中不属于您的位置时,可能会发生段错误,即 UB。 (但是,通过查看您的代码并不清楚这是正在发生的事情,只是猜测)
另一种创建和初始化指针的常规方法,然后创建space(超过两个字节):
String hash_guess = {0};
hash_guess = calloc(10, 1);
if(hash_guess)
{
//... (your code here)
//hash_guess can now contain up to 9 characters and the NULL terminator.
}
free(hash_guess);
好的,仅供参考,段错误的原因是您正在使用编译器的只读内存作为临时存储。
typedef string char*;
string hash_guess = "A";
编译器生成一个包含 'A' 和 '\0' 的 2 条目常量内存数组。您不能写入此内存。这是未定义的行为。 (UB)
while(hash_guess[0] <= 'Z' && hash_guess[0] >= 'A')
{
hash_guess[0] = hash_guess[0] + 1;
...
是非法的。您需要一个临时字符数组来保持您的猜测是合法的。
char my_guess[5]; // You specify a max length of 4. Make a constant soon please.
strcpy(my_guess, hash_guess); // Real code never uses this function for safety reasons.
// Beware that later when going to multi-letter check, you will
// need to re- NUL terminate the string...
while(my_guess[0] <= 'Z' && my_guess[0] >= 'A')
{
my_guess[0] = my_guess[0] + 1;
// ...
my_guess
在堆栈上并且可以安全使用。
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <crypt.h>
int main(int argc, string argv[])
{
if(argc > 2){ printf("too many arguments\n"); return 51; }
if(argc < 2){ printf("too few arguments\n"); return 50; }
if(strlen(argv[1]) > 4){ printf("Password is greater than 4 characters\n"); return 52; }
if(argc == 2) //make sure there are enough args
{
string hash_guess = "A";
while(crypt(hash_guess, "50") != argv[1]) //while answer not correct
{
while(hash_guess[0] <= 'Z' && hash_guess[0] >= 'A')
{
hash_guess[0] = hash_guess[0] + 1;
printf("%s", hash_guess);
}
}
}
}
我试图通过一个单词逐个字母递增,所以它会先是 a,然后是 b,然后是 c,直到 z,然后它会变成 aa、ab、ac、ad....然后是 ba bb bc bd .. . 然后 za...zz...zzz。我从一个字母开始,但出现错误 "segmentation fault"
我很惊讶你遇到段错误。您显示的代码甚至不应该编译。
行:
string hash_guess = "A";
使用 string
作为类型。除非您在未显示的部分代码中使用了 typedef string
,否则它不能用于创建变量。
尝试:
char hash_guess[] = "A";//creates array of char, 2 bytes long: |A|0|
即便如此,如果您需要此变量包含超过 2 个字节,请使用更多 space:
创建它 char hash_guess[10] = "A"; Creates space for 10 bytes: |A|0|0|0|0|0|0|0|0|0|
请记住,C 字符串被定义为以 NULL 结尾的字符数组。
编辑 根据@MichaelDorgan 的发现,cs50
typedefs String
as char *
。所以违规行现在等同于:
char *hash_guess = "A";
这就是它编译和运行的原因。当您明确尝试写入内存中不属于您的位置时,可能会发生段错误,即 UB。 (但是,通过查看您的代码并不清楚这是正在发生的事情,只是猜测)
另一种创建和初始化指针的常规方法,然后创建space(超过两个字节):
String hash_guess = {0};
hash_guess = calloc(10, 1);
if(hash_guess)
{
//... (your code here)
//hash_guess can now contain up to 9 characters and the NULL terminator.
}
free(hash_guess);
好的,仅供参考,段错误的原因是您正在使用编译器的只读内存作为临时存储。
typedef string char*;
string hash_guess = "A";
编译器生成一个包含 'A' 和 '\0' 的 2 条目常量内存数组。您不能写入此内存。这是未定义的行为。 (UB)
while(hash_guess[0] <= 'Z' && hash_guess[0] >= 'A')
{
hash_guess[0] = hash_guess[0] + 1;
...
是非法的。您需要一个临时字符数组来保持您的猜测是合法的。
char my_guess[5]; // You specify a max length of 4. Make a constant soon please.
strcpy(my_guess, hash_guess); // Real code never uses this function for safety reasons.
// Beware that later when going to multi-letter check, you will
// need to re- NUL terminate the string...
while(my_guess[0] <= 'Z' && my_guess[0] >= 'A')
{
my_guess[0] = my_guess[0] + 1;
// ...
my_guess
在堆栈上并且可以安全使用。