2016-05-02 13 views
0

私はVS 2015で実行するとEclipseの私のコードの非常に奇妙なエラー、持っている:セグメンテーションフォールト(変数corupted)

int main(int argc, const char**argv) { 
FILE *input = stdin; 
FILE *output = stdout; 
if(!argumentsValid(argv, argc)){ 
    mtmPrintErrorMessage(stderr, MTM_INVALID_COMMAND_LINE_PARAMETERS); 
    return 1; 
} 
if(!changeIO(&input, &output, argv, argc)){ 
    mtmPrintErrorMessage(stderr, MTM_CANNOT_OPEN_FILE); 
    return 1; 
} 
char buffer[MAX_LEN + 1]; 
Yad3Service yad3Service = yad3ServiceCreate(); 
if(!yad3Service){ 
    mtmPrintErrorMessage(stderr, MTM_OUT_OF_MEMORY); 
    deallocateAndClose(input, output, &yad3Service); 
} 
int j = 0; 
while (fgets(buffer, MAX_LEN, input) != NULL) { 
    j++; 
    printf("%d\n", j); 
    char command_p1[10]; 
    strcpy(command_p1, strtok(buffer, " ")); 
    if (!strcmp(command_p1, "\n") || command_p1[0] == '#') continue; 
    char command_p2[30]; 
    strcpy(command_p2 + 1, strtok(NULL, " ")); 
    command_p2[0] = ' '; 
    char command[40]; 
    strcpy(command, strcat(command_p1, command_p2)); 
    char* command_arguments[10]; 
    int i = 0; 
    while((command_arguments[i++] = strtok(NULL, " "))); 
    Yad3ServiceResult res = command_parser(&yad3Service, command, 
            command_arguments, output); 
    if(res != YAD3_SUCCESS){ 
     if(res == YAD3_OUT_OF_MEMORY){ 
      deallocateAndClose(input, output, &yad3Service); 
      mtmPrintErrorMessage(stderr, ((MtmErrorCode)((int)res))); 
      return 1; 
     } 
     mtmPrintErrorMessage(stderr, ((MtmErrorCode)((int)res))); 
    } 
} 
deallocateAndClose(input, output, &yad3Service); 
return 0; 

}

を問題どのVisual Studioは、リターンコマンドの後に、プログラムの最後にある与えます:しばらく34の繰り返しで、

Run-Time Check Failure #2 - Stack around the variable 'command_p1' was corrupted. 

と日食が何かさえ知らない人がやっている、などであるYad3Service(の内側のフィールドその中に割り当てられたメモリを持つ構造体)をクリアし、内部アドレスが(デバッグ時に)存在しないように見えるだけで、構造体のポインタの内部フィールドに次にアクセスするときにセグメンテーションフォールトが発生します。

多分strcpyやstrtok中にどうやって破壊されたメモリについて、私は何が起こるか理解していません。誰か ???

奇妙な消失は、行をやった後起こる:

strcpy(command, strcat(command_p1, command_p2)); 
+0

あなたのコードを詳しく調べることなく、文字列を小さすぎるバッファにコピーしようとしているときにエラーが発生することはほとんどありません(さらに悪いことに、ポインタが迷惑ポインタであることが指摘されています)。 –

+0

多分私はバッファをフラッシュする必要がありますか? – KittyT2016

+0

'strcat(command_p1、command_p2)'はうんざりしているようです - 'command_p1'は' command_p2'より* small *です。 –

答えて

2

あなたがここでの問題のすべての種類を持っています。 まず、ライン:ここでは二つの問題があります

strcpy(command_p1, strtok(buffer, " ")); 

まずbufferがあなたのstrcpyのために無効である、空の文字列を、(含まれている場合、はstrtok())はNULLを返します。

第2に、command_p1はchar [10]の配列として宣言されています。 bufferの最初のトークンが決して9文字(ヌルターミネータを含まない)以上になることは絶対に確実ですか?これは常に事前に確認するか、strlcpy()http://linux.die.net/man/3/strlcpy)をシステムで使用できる場合は使用してください。何をコピーしているのかわからないときは、strcpy()を使用しないでください。同じ注意事項は、あなたのプログラムの中で取り扱うすべての文字列に適用されます

char mybuffer[100]; 

/* copy as much of mysource into mybuffer as will fit. */ 
/* the result may NOT be null terminated    */ 
strncpy(mybuffer, mysource, sizeof(mybuffer)); 

/* make sure the string is null terminated */ 
mybuffer[sizeof(mybuffer)-1] = 0; 

:あなたは、次の一般的なイディオムを使用することができますstrlcpyに持っていない場合。いくつかの場所では、文字列の長さについて仮定しているので、Cでプログラミングするときは決して行うべきではありません。

文字列バッファにコピーする内容NULLポインタになる可能性がありますまたは期待よりも大きくなる可能性があります。これらすべてを修正すれば、あなたのプログラムはおそらく動くでしょう。もしそうでなければ、あなたは本当に間違っていることを理解するのにもっと良い立場にいるでしょう。

1

strcat(t,s)を連結終了ts。したがって、tに割り当てられた領域は、tが現在保持している文字列と、sの両方を保持するのに十分なほど大きいことが必要です。あなたのケースでは、

char command_p1[10]; 
char command_p2[30]; 

を持っしたがって

strcat(command_p1, command_p2) 

は、バッファオーバーフローを危険にさらしています。エラーメッセージは、実際にこれが発生することを示します。

関連する問題