簡體   English   中英

分段錯誤 - strcpy() - C.

[英]Segmentation Fault - strcpy() - C

我正在為命令行shell實現歷史記錄功能。 我已經實現了一個循環數組來保存十個最近的命令。 每個命令也用整數標記,指定總命令是什么。 例如,如果輸入了30個命令,則圓形數組中的10個命令將被編號(30,29,28,27,...,21)。

如果用戶要插入命令“r”,后跟一個標記十條指令之一的數字,那么該指令應該運行。 在嘗試確保正確接受雙字命令時,我一直遇到段故障。 任何人都可以幫助指出問題是什么。

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. */
    }
}

任何幫助表示贊賞!

-MATT

這里你的args是字符指針數組。

但是strcpy需要兩個參數 - 應該是character pointer to which memory allocated by malloc arraycharacter pointer to which memory allocated by malloc

但是你的strcpy(historyArray[position],args[0]); 將一個參數作為不接受的character pointer

這樣你就可以改變args[]args[][]args[0] = malloc(some_no) segfault將被刪除。

您注意到崩潰發生在該行上

else if(!strcmp("r",args[0]))

如果我是你,我會在調試器中加載核心文件,看看傳遞給strcmp()args[0]的值是什么。

我希望你有關於charchar*之間類型不匹配的編譯器警告。 你將args聲明為char* 這意味着args[0]char ,而不是char* 要比較單個字符,只需使用一個字符而不是strcmp()

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

關於C字符串處理的陷阱的一些注意事項:

  • strcmp()在其參數未正確NUL終止時對於數組邊界是不安全的
    • 使用strncmp()來提供對比的字符數限制
  • 雖然strncpy()防止數組邊界,但它不能保證NUL終止目標字符串
  • strcpy()不尊重數組邊界; 您有責任確保目標數組足夠大以接收要復制到其中的字符串

你缺少分配內存的argsholderchar指針。

因此,通過str*()系列函數引用那些作為0終止字符數組(“字符串”)的指針,導致未定義的行為,因為str*()函數試圖降低那些指向不指向有效內存的指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM