分段错误-strcpy()-C
我正在为命令行shell实现一个历史记录功能。我已经实现了一个循环数组来保存十个最新的命令。每个命令还由一个整数标记,该整数指定命令总数。例如,如果总共输入了30条命令,则圆形数组中的10条命令将被编号(30、29、28、27、…、21) 如果用户要插入命令“r”,然后插入一个数字,标记十条指令中的一条,则该指令应该运行。在尝试确保两个字的命令被正确接受时,我总是遇到seg故障。谁能帮我指出问题出在哪里分段错误-strcpy()-C,c,segmentation-fault,strcpy,C,Segmentation Fault,Strcpy,我正在为命令行shell实现一个历史记录功能。我已经实现了一个循环数组来保存十个最新的命令。每个命令还由一个整数标记,该整数指定命令总数。例如,如果总共输入了30条命令,则圆形数组中的10条命令将被编号(30、29、28、27、…、21) 如果用户要插入命令“r”,然后插入一个数字,标记十条指令中的一条,则该指令应该运行。在尝试确保两个字的命令被正确接受时,我总是遇到seg故障。谁能帮我指出问题出在哪里 int main(void) { char inputBuffer[MAX_LINE
int main(void)
{
char inputBuffer[MAX_LINE]; /* buffer to hold the command entered */
int background; /* equals 1 if a command is followed by '&' */
char *args[MAX_LINE/2+1];/* command line (of 80) has max of 40 arguments */
int position, count, rnum = 0;
char historyArray[10][MAX_LINE];
char *holder[MAX_LINE]={0};
while (1){ /* Program terminates normally inside setup */
background = 0;
printf("COMMAND->");
fflush(0);
setup(inputBuffer, args, &background); /* get next command */
position = (count % MOD_VAL);
strcpy(historyArray[position],args[0]);
if(!strcmp("rr",args[0]))
{
strcpy(historyArray[position],historyArray[((position-1)+MOD_VAL)%MOD_VAL]);
printf("%i",count);
printf("%c",'.');
printf("%c",' ');
printf("%s",historyArray[position]);
printf("%c",'\n');
strcpy(args[0],historyArray[position]);
}
else if(!strcmp("r",args[0])) //SEG FAULT OCCURING IN THIS ELSE-IF BLOCK!
{
//args[1] will hold given number
printf("%c",'\n');
printf("%s",args[0]);
printf("%s",args[1]);
printf("%s",args[2]);
printf("%c",'\n'); //PRINT STATEMENTS FOR DEBUGGING
strncpy(holder[0], args[2], MAX_LINE - 1); //SEG FAULT
rnum = atoi(args[1]);
strcpy(historyArray[position],historyArray[((position-(count-rnum))+MOD_VAL)%MOD_VAL]);
strcpy(args[0],historyArray[position]); //CHANGES VALUES OF args[1], args[2]
if(holder[0] != NULL)
{
strncpy(args[1],holder[0],MAX_LINE-1);
args[2] = NULL;
}
else
{
args[1] = NULL;
}
printf("%c",'\n');
printf("%s",args[0]);
printf("%s",args[1]);
printf("%s",args[2]);
printf("%c",'\n');
}
else if(!(strcmp("h",args[0]))||!(strcmp("history",args[0])))
{
int counter = 0;
while(counter < 10)
{
printf("%i",(count - counter));
printf("%c",'.');
printf("%c",' ');
printf("%s", historyArray[((position - counter + MOD_VAL)%MOD_VAL)]);
printf("%c",' ');
printf("%c",'\n');
counter ++;
if(counter > count)
break;
}
}
count++;
pid_t pid1; //Initialize pid_t variable to hold process identifier
pid1 = fork(); //Fork process and assign process identifier to "pid1"
if (pid1 == 0) //Child process
{
//Child process executes the command specified by the user and
//then quits.
execvp(args[0], args);
exit(0);
}
else //Parent process
{
if (background != 1)//Check for inclusion of '&' in command
{
wait(NULL); //Wait for child process to finish executing
}
}
/* the steps are:
(1) fork a child process using fork()
(2) the child process will invoke execvp()
(3) if background == 0, the parent will wait,
otherwise returns to the setup() function. */
}
}
int main(无效)
{
char inputBuffer[MAX_LINE];/*用于保存输入命令的缓冲区*/
int background;/*如果命令后跟“&”,则等于1*/
char*args[MAX_-LINE/2+1];/*命令行(共80个)最多有40个参数*/
int位置,计数,rnum=0;
字符历史数组[10][MAX_LINE];
char*holder[MAX_LINE]={0};
而(1){/*程序在安装程序内正常终止*/
背景=0;
printf(“命令->”);
fflush(0);
安装程序(inputBuffer、args和background);/*获取下一个命令*/
位置=(计数%MOD_VAL);
strcpy(historyArray[position],args[0]);
如果(!strcmp(“rr”,参数[0]))
{
strcpy(historyArray[position],historyArray[(position-1)+MOD_VAL)%MOD_VAL]);
printf(“%i”,计数);
printf(“%c”,”);
printf(“%c”,”);
printf(“%s”,historyArray[position]);
printf(“%c”,“\n”);
strcpy(args[0],historyArray[position]);
}
else-if(!strcmp(“r”,args[0])//此else-if块中发生SEG错误!
{
//args[1]将保存给定的数字
printf(“%c”,“\n”);
printf(“%s”,参数[0]);
printf(“%s”,args[1]);
printf(“%s”,args[2]);
printf(“%c”,“\n”);//打印调试语句
strncpy(保持架[0],参数[2],最大线路-1);//SEG故障
rnum=atoi(args[1]);
strcpy(历史数组[position],历史数组[((position-(count rnum))+MOD_VAL)%MOD_VAL]);
strcpy(args[0],historyArray[position]);//更改args[1],args[2]的值
if(保持器[0]!=NULL)
{
strncpy(args[1],holder[0],MAX_LINE-1);
args[2]=NULL;
}
其他的
{
args[1]=NULL;
}
printf(“%c”,“\n”);
printf(“%s”,参数[0]);
printf(“%s”,args[1]);
printf(“%s”,args[2]);
printf(“%c”,“\n”);
}
如果(!(strcmp(“h”,args[0]))| |!(strcmp(“history”,args[0]))
{
int计数器=0;
while(计数器<10)
{
printf(“%i”,(计数-计数器));
printf(“%c”,”);
printf(“%c”,”);
printf(“%s”,历史数组[(位置-计数器+MOD_VAL)%MOD_VAL)];
printf(“%c”,”);
printf(“%c”,“\n”);
计数器++;
如果(计数器>计数)
打破
}
}
计数++;
pid_t pid1;//初始化pid_t变量以保存进程标识符
pid1=fork();//分叉进程并将进程标识符分配给“pid1”
if(pid1==0)//子进程
{
//子进程执行用户指定的命令,并
//然后退出。
execvp(args[0],args);
出口(0);
}
else//父进程
{
if(background!=1)//检查命令中是否包含“&”
{
wait(NULL);//等待子进程完成执行
}
}
/*这些步骤是:
(1) 使用fork()派生子进程
(2) 子进程将调用execvp()
(3) 如果background==0,则父级将等待,
否则返回setup()函数*/
}
}
感谢您的帮助
-MATT您注意到碰撞发生在线路上
else if(!strcmp("r",args[0]))
如果我是你,我会在调试器中加载核心文件,并查看args[0]
在传递到strcmp()
时的值
我希望您有编译器警告,说明char
和char*
之间的类型不匹配。将args声明为char*
。这意味着args[0]
是char
,而不是char*
。要比较单个字符,只需使用字符而不是strcmp():
关于C的字符串处理陷阱的一些注意事项:
在其参数未正确以NUL结尾时,对于数组边界而言是不安全的strcmp()
- 使用
对比较的字符数进行限制strncmp()
- 使用
- 虽然
可以防止数组边界,但它不能保证NUL终止目标字符串strncpy()
不尊重数组边界;您有责任确保目标阵列足够大,可以接收复制到其中的字符串strcpy()
strcpy
需要两个参数,它们应该是array
或字符指针,malloc向其分配内存
但是您的strcpy(historyArray[position],args[0])
将一个参数作为字符指针
,该参数将不被接受
因此,您可以将args[]
更改为args[][]
或args[0]=malloc(某些编号)
,segfault
将被删除。您缺少args
和holder
中保存的char
指针来分配内存
所以
else if ('r' != args[0])