Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
分段错误-strcpy()-C_C_Segmentation Fault_Strcpy - Fatal编程技术网

分段错误-strcpy()-C

分段错误-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

我正在为命令行shell实现一个历史记录功能。我已经实现了一个循环数组来保存十个最新的命令。每个命令还由一个整数标记,该整数指定命令总数。例如,如果总共输入了30条命令,则圆形数组中的10条命令将被编号(30、29、28、27、…、21)

如果用户要插入命令“r”,然后插入一个数字,标记十条指令中的一条,则该指令应该运行。在尝试确保两个字的命令被正确接受时,我总是遇到seg故障。谁能帮我指出问题出在哪里

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的字符串处理陷阱的一些注意事项:

  • strcmp()
    在其参数未正确以NUL结尾时,对于数组边界而言是不安全的
    • 使用
      strncmp()
      对比较的字符数进行限制
  • 虽然
    strncpy()
    可以防止数组边界,但它不能保证NUL终止目标字符串
  • strcpy()
    不尊重数组边界;您有责任确保目标阵列足够大,可以接收复制到其中的字符串

这里的参数是字符指针数组

但是,
strcpy
需要两个参数,它们应该是
array
字符指针,malloc向其分配内存

但是您的
strcpy(historyArray[position],args[0])
将一个参数作为
字符指针
,该参数将不被接受


因此,您可以将
args[]
更改为
args[][]
args[0]=malloc(某些编号)
segfault
将被删除。

您缺少
args
holder
中保存的
char
指针来分配内存

所以
else if ('r' != args[0])