命令行参数分段错误(核心转储)
Posted
技术标签:
【中文标题】命令行参数分段错误(核心转储)【英文标题】:Command line argument Segmentation fault (core dumped) 【发布时间】:2014-06-05 23:26:09 【问题描述】:我了解分段错误意味着我正在尝试使用我不应该接触的内存,但我无法弄清楚它在我的代码中来自哪里。我为一个作业编写了一个程序,该程序使用 vigenere 的密码来加密一些纯文本。它编译得很好,但是当我使用命令行参数运行它时,我得到了一个分段错误。
#include <cs50.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int main(int argc, string argv[])
// check to make sure the user entered a key
if(argc != 2)
printf("You need to enter a key, and only one. Please enter an alphabetical key. \nSyntax: ./vigenere key \n");
exit (1);
// check to make sure the key is alphabetical
string k = argv[1];
if(isalpha(k) == false)
printf("Pleas enter an alphabetical key.\n");
exit (2);
// Get a string of plaintext
printf("Please enter your secret messege.\n");
string p = GetString();
// Encipher
int lk = strlen(k);
int lp = strlen(p);
for(int i = 0, j = 0; i < lp; i++, j++)
if(isupper(k[j]))
tolower(k[j]);
if(j > lk)
j = 0;
if(isalpha(p[i]))
if (islower(p[i]))
printf("%c", ((((p[i] - 97) + (k[j] - 97)) %26) +97));
else
printf("%c", ((((p[i] - 65) + (k[j] - 97)) %26) +65));
else
printf("%c", p[i]);
printf("\n");
return 0;
【问题讨论】:
只需使用调试标志编译您的程序(例如,-g
,如果您使用 gcc)并使用调试器运行程序(例如,gdb
)。它会显示导致段错误的行。
您的一个数组可能超出范围,正如 Pavel 所说,使用调试器。
【参考方案1】:
这段代码看起来很可疑:
if(isupper(k[j]))
tolower(k[j]);
if(j > lk)
j = 0;
您使用了 k[j],但之后的检查表明 j 可能大于 lk。所以 k[j] 可能超出范围。
【讨论】:
【参考方案2】:您的if(isalpha(k) == false)
行没有检查整个字符串。 isalpha() 只接受一个整数参数。
您必须查看整个字符串并为每个字符调用 isalpha()。
for( size_t i = 0 ; i < strlen( k ) ; i++ )
if(isalpha(k[i]) == false)
printf("Pleas enter an alphabetical key.\n");
exit (2);
【讨论】:
我在以这种错误的方式实现 isalpha() 时遇到了分段错误。使用循环是我需要的。同样的任务(cs50)!【参考方案3】:要解决此代码问题,我们需要知道 cs50.h 中的内容、数据类型“string”的定义方式以及 GetString() 是什么。分段错误可能发生在以下行: string p = GetString();如果 p 是一个指针并且没有分配内存来存储 GetString() 返回的“字符串”。
如果不包含 cs50.h,则“字符串”被重新定义为字符数组,并且 GetString() 被 fgets() 替换(以及一些其他小的更改),代码可以正常工作。请参阅下文,并根据您的班级需要对其进行调整。
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
// check to make sure the user entered a key
if (argc != 2)
printf("You need to enter a key, and only one. Please enter an alphabetical key. \nSyntax: ./vigenere key \n");
exit (1);
// check to make sure the key is alphabetical
//string k = argv[1];
char *k = argv[1];
char *sp;
for (sp = argv[1]; *sp != '\0'; sp++)
if(!isalpha(*sp))
printf("Pleas enter an alphabetical key.\n");
exit (2);
// Get a string of plaintext
printf("Please enter your secret message.\n");
//string p = GetString();
char p[256];
fgets(p, 256, stdin);
// Encipher
int lk = strlen(k);
int lp = strlen(p);
int i;
int j;
for(i = 0, j = 0; i < lp; i++, j++)
if(isupper(k[j]))
k[j] = tolower(k[j]);
if(j > lk)
j = 0;
if(isalpha(p[i]))
if (islower(p[i]))
printf("%c", ((((p[i] - 97) + (k[j] - 97)) %26) +97));
else
printf("%c", ((((p[i] - 65) + (k[j] - 97)) %26) +65));
else
printf("%c", p[i]);
printf("\n");
return 0;
【讨论】:
以上是关于命令行参数分段错误(核心转储)的主要内容,如果未能解决你的问题,请参考以下文章
aio_write 和 memset 无效参数和分段错误(核心转储)