我已经看过网站上的其他类似问题,但我仍然没有看到我错过的内容。 C对我来说是一个新的,可怕的野兽,所以我确定它很简单,但是当代码到达fgets();
行时,我会遇到分段错误(核心转储)在while循环中。
我尝试将字符串直接写入currentInput
而仍然得到它,所以我想我以某种方式错误地访问字符串?
我的理解是,通过访问(程序?)无法访问的内存导致分段错误...
顺便说一下,有没有办法在strcmp()中使用字符串文字;所以我可以比较" END"?
void runCommands()
{
char * currentInput = (char*)malloc(100); //100 char input buffer
char * cmd = (char*) malloc(CMD_LENGTH);
char * target = (char*) malloc(UID_LENGTH);
char * key = (char*) malloc(KEY_LENGTH);
char * endstr = "END";
cmd = "UNDEF";
target = "UNDEF";
key = "UNDEF";
ushort tokens;
while (strcmp(cmd, endstr) != 0) //Run until command is "END"
{
printf("ENTER INSTRUCTION: ");
fgets(currentInput, sizeof(currentInput), stdin); //FAULT OCCURS HERE
tokens = sscanf(currentInput, "%[^,\n],%[^,\n],%s", cmd, target, key); //parse string for values
if (tokens <= 3 && tokens >= 1) //ensure valid # of tokens passed
{
fprintf(stdout, "TOKENS:\nCMD: %s\ntarget: %s\nkey: %s\n", cmd, target, key);
switch (tokens)
//restore UNDEF for non-existent tokens
{
case 1:
target = "UNDEF";
/* no break */
case 2: //intentional fallthrough
key = "UNDEF";
break;
default:
break;
}
/* handle commands */
if (strcmp(cmd, endstr) == 0)
{
end(keyfile);
} //write file and exit function
else if (strcmp(cmd, "DELETE") == 0)
{
delete(target, key);
} //delete specified key from UID
else if (strcmp(cmd, "VALIDATE") == 0)
{
validate(target, key);
} //valid/not valid based on key presence
else if (strcmp(cmd, "ADD") == 0)
{
add(target, key);
} //add key to target UID
else if (strcmp(cmd, "PRINT") == 0)
{
print(target);
} //print sorted keys for UID or all keys for ALL
else
{
invalidCMD(cmd);
} //error message for invalid command
}
else
{
invalidCMD(currentInput); //use whole input as bad command if invalid format
}
}
free(currentInput);
free(target);
free(key);
free(cmd);
}
答案 0 :(得分:2)
通过覆盖malloc返回的指针值,导致内存泄漏和未定义的行为:
char * currentInput = (char*)malloc(100); //100 char input buffer
char * cmd = (char*) malloc(CMD_LENGTH);
char * target = (char*) malloc(UID_LENGTH);
char * key = (char*) malloc(KEY_LENGTH);
//...
// This is where you cause the issue
char * endstr = "END";
cmd = "UNDEF";
target = "UNDEF";
key = "UNDEF";
由于您关闭了代码,我无法对您的其余代码发表评论,以确定还会导致问题。
有一点是你肯定没有正确使用sizeof()
,因为sizeof(currentInput)
等于sizeof(char*)
,而不是字符串的长度。
答案 1 :(得分:1)
当您编写cmd = "UNDEF"
时,您将指针(即cmd
)设置为文字字符数组的位置。如果要分配字符串(而不是指向它们的字符串),则应使用strcpy
。
C编译器会自动为字符串常量分配空间,但是,它不允许重写它们,您可能会尝试在您省略的代码部分中进行重写。
答案 2 :(得分:0)
你需要读一下C类型和指针.. :)考虑下面的变化:
#define CMD_LENGTH 100
#define UID_LENGTH 100
#define KEY_LENGTH 100
void runCommands()
{
char * currentInput = (char*)malloc(100); //100 char input buffer
char * cmd = (char*) malloc(CMD_LENGTH);
char * target = (char*) malloc(UID_LENGTH);
char * key = (char*) malloc(KEY_LENGTH);
char * endstr = (char *)malloc(sizeof(char) * 100);
ushort tokens;
strcpy(cmd, "UNDEF");
strcpy(target, "UNDEF");
strcpy(key, "UNDEF");
while (strcmp(cmd, endstr) != 0) //Run until command is "END"
{
printf("ENTER INSTRUCTION: ");
fgets(currentInput, sizeof(currentInput), stdin);
您不能使用简单的赋值以这种方式将值放入指针。这样做有效地覆盖指针与任何&#34; END&#34; (例如)转换为十六进制,这不是您的进程拥有的内存位置。实际上,如果您收到分段错误,通常意味着您尝试读取您不拥有的内存,而访问冲突通常是尝试写入您不拥有的内存。
我预计你的大部分麻烦都是由无意中覆盖指针造成的。
使用&#34;魔术数字&#34; ...(例如,神奇地分配100个字节,这也是非常糟糕的做法。你怎么知道它的100?它总是100?)您还应该验证malloc实际上是否返回了一个值,而不是假设它已经返回。调用Malloc的更典型方式也有说明,但我没有验证返回。最后,fgets是超级危险的,因为它是一个无限的读数。您更喜欢使用允许您指定要读取的最大大小的函数,以避免堆或堆栈上的溢出条件(取决于它是局部变量,全局变量还是指向堆的指针)。 / p>