具有多个命令的C外壳,分段错误(内核转储)
我正试图用C语言为ubuntu编写一个基本的shell。我想在一行中执行几个命令,用分号分隔。我正在尝试运行它,但我得到消息“分段错误(核心转储)”具有多个命令的C外壳,分段错误(内核转储),c,shell,C,Shell,我正试图用C语言为ubuntu编写一个基本的shell。我想在一行中执行几个命令,用分号分隔。我正在尝试运行它,但我得到消息“分段错误(核心转储)” #包括 #包括 #包括 #包括 #包括 #ifdef_WIN32 #包括 #定义chdir\u chdir #否则 #包括 #恩迪夫 #定义最大长度512 int main(int argc,char*argv[]){ char*cmd; 字符行[最大长度]; 字符*令牌[20]; int i=0; int j=0; int k=0; char*a
#包括
#包括
#包括
#包括
#包括
#ifdef_WIN32
#包括
#定义chdir\u chdir
#否则
#包括
#恩迪夫
#定义最大长度512
int main(int argc,char*argv[]){
char*cmd;
字符行[最大长度];
字符*令牌[20];
int i=0;
int j=0;
int k=0;
char*args[20];
而(1){
printf(“8334>”);
如果(!fgets(直线,最大长度,标准长度))中断;
while((cmd=strtok(行“;”)!=NULL)
{
printf(“\n”,cmd);
strcpy(令牌[i],cmd);
i+=1;
cmd=NULL;
}
对于(j=0;j,我看到的主要问题是,您没有为将字符串复制到args[I]
和token[I]
预留空间;您为指针数组预留空间,但不为指针指向的内容预留空间:
char *token[20]; // reserves place for 20 pointers
...
strcpy(token[i], cmd); // token[i] has not been initialized...
克服这一问题最简单的方法可能是写作
token[i] = strdup(cmd);
请注意,strdpy
,而不是strcpy
;请注意,strdup
会自动为保存副本保留足够的内存,而strcpy
希望此空间以前已被保留
无论如何,不要忘记在不再使用时释放此内存,也不要忘记对args
执行此操作
代码中可能还有其他问题;例如,当使用strtok
时,只有第一个调用会通过split行,而所有连续调用都应该通过NULL
(请参见doku)。但我认为这是您和调试器可以达到的级别:-)问题的根源在于这一行:
strcpy(token[i], cmd);
这是试图将该字符串复制到char*token[20]
中的一个条目,但这只是一个指针数组,而不是字符串指针数组
也许你可以使用:
token[i] = strdup( cmd );
当然,代码需要检查(!=NULL)token[i]
以确保对strdup()
的调用成功,并在使用特定命令后,将该指针传递到free()
类似的注意事项也适用于char*args[20];
usage您的调试器在这里将非常有用。您不知道如何使用调试器?那么是时候开始学习了。为了便于阅读和理解,1)一致地缩进代码。在每个左大括号“{.unindent”之后缩进,在每个右大括号之前缩进(2)遵循公理:每条语句只有一条语句(至多)每个语句的一个变量声明。考虑关闭括号作为单独的语句。3)变量名应该指示内容或用法(或更好,两者都有)。变量名LIE <代码> L>代码>不给出这样的信息。
将不使用,然后使用签名:int main(void)
为了便于阅读和理解,单独的代码块(for、if、else、while、do…while、switch、case、default)通过一条空行,发布的代码包含一些“神奇”数字。例如,20。“神奇”数字是没有基础的数字。建议使用#define
或enum
语句为这些神奇数字指定有意义的名称,然后在整个代码中使用这些有意义的名称。
token[i] = strdup( cmd );