2017-01-15 12 views
0

シェル(Linux、GCC、C言語)を実装するコードを書きましたが、すべて動作しますが、ヒストリオプションを追加したときに何らかの理由でコードがクラッシュします: 本当に't(他のコード)なので、ここでは必要なものだけを入れます。シェルの実装の履歴はセグメンテーションエラーを受け取ります

問題は、履歴に保存する必要がある古いコマンドの後にquitと入力したときに、終了入力するとセグメンテーションフォルト(コアがダンプされた)で破棄されるだけです。

履歴は、リンクされたリスト、コマンドの文字列、次のノードのノードの構造体に保存されます。また、ヘッドをメインに保存しました。ポイントは最後のコマンドを15個だけ保存したいのですが、他のコマンドは気にしないので、リストを印刷するたびにループの最初の15個のノードに移動しました。

私はGDBでデバッグするとき、私は彼が歴史が、現在のラインが本当に歴史に関連していない最初のコマンドを追加した後の行のコードがクラッシュしたラインであることを見た:
メイン:

int main() 
{ 
    history_ll* top; 
    char userInput [CHOICE_LENGTH]; 
    char buff[PATH_MAX]; 
    int flag=1; 
    cmdLine * head; 
    while (flag) 
    { 
     getcwd(buff, PATH_MAX); 
     printf("%s:~$ ",buff); 
     fgets(userInput,MAX_INPUT, stdin); 
     userInput[strlen(userInput)-1]=0; 
     historyAdder(userInput,&top); 
     if(strcmp(userInput,QUIT_OPTION)==0) //segmentation fault here! 
     { 
      flag=0; 
     } 
     else 
     { 
      //doesn't matter 
     } 

    } 
    return 0; 
} 

historyAdderは次のようになります。

void historyAdder(const char *command,history_ll** top) 
{ 
    history_ll* node; 
    strcpy(node->command,command); 
    node->command[strlen(command)]=0; 
    if(historyLength!=0) 
    { 
     node->next= *top; 
    } 
    else 
    { 
     node->next= NULL; 
    } 
    *top = node; 
    historyLength++; 
} 

注:historyLengthはグローバル変数

01です

これは構造体である:

typedef struct history_ll{ 
    char command[CHOICE_LENGTH]; 
    struct history_ll *next; 
}history_ll; 

はあなたのヘルパーをありがとう!

答えて

0
ここ

(及び行に以下)

void historyAdder(const char *command,history_ll** top) 
{ 
    history_ll* node; 
    strcpy(node->command,command); 
    ... 

コードが初期化されていないポインタを間接参照:nodeそうでUBを呼び出し、ほとんどありそうなプログラムがクラッシュ。

0

これはあるおそらく問題:MAX_INPUT以上である

char userInput [CHOICE_LENGTH]; 
... 
fgets(userInput,MAX_INPUT, stdin); 

CHOICE_LENGTHない限り、fgetsがクラッシュにつながる、userInput配列、意志破損しているメモリの終わりを過ぎて書くことができます。しかし、のプログラムを自分でコンパイルしてクラッシュすることはできないので、私は確信が持てません。あなたのためのアドバイスの

2枚:

  • あなたは、Linuxにしているので、あなたはgetlineを持っています。 fgetsの代わりにそれを使用すれば、入力バッファのサイズを気にする必要はありません。

  • セグメンテーションフォールトでクラッシュするプログラムがある場合は、最初に到達するのはvalgrindです。非常に頻繁に、valgrindは、リアルのバグが、あなたが思っていたどこにも近くにないことを明らかにするでしょう。

1

このコードには少なくとも2つの重要な問題があります。 一つは、あなたが標準入力から読んだとき、バッファ長が短すぎネブラスカかもしれないということです: 定義:

char userInput [CHOICE_LENGTH]; 

が、使用法は次のとおりです。

fgets(userInput,MAX_INPUT, stdin); 

あなたは同じバッファサイズを使用するか、MAX_INPUTを主張すべきことは以下であり、 CHOICE_LENGTH

第二

、あなたがここに初期化されていないポインタを参照解除することにより、未定義の動作をトリガー:

void historyAdder(const char *command,history_ll** top) 
{ 
    history_ll* node; 
    strcpy(node->command,command); /* bad... */ 
関連する問題