4

私は主に C スキルを磨くために K&R C を読んでいて、特定の文字列を反転するプログラムをコーディングしようとしているときに、厄介なバグがあり、最悪の場合、デバッグできません。その原因は何なのかを探ります。

私のコードは次のとおりです。

#include <stdio.h>
#include <string.h>

char * reverse(char *string);

int main(int argc, char *argv[])
{
    printf("Please input a string: \t");

    char string[256];

    scanf("%s", string);

    char *reversed = reverse(string);

    printf("The reversed string is %s\n", reversed);

    return 0;
}

char * reverse(char string[])
{
    int size = strlen(string);
    printf("DEBUG: The size of the string that we got as input was: %d\n", size);
    int counter;
    char reversed[size + 1];

    for(counter = size - 1; counter >= 0; counter--) {
        reversed[size - counter] = string[counter];
        printf("DEBUG: The character copied now was %c and was at index %d\n", string[counter], counter);
    }

    reversed[size + 1] = '\0';

    printf("DEBUG: The reversed string is %s\n", reversed);

    return reversed;
}

(コード ロジックに散らばるデバッグ ステートメントをご容赦ください。それとは別に、見られる可能性のある間違いを自由に修正してください。また、それを改善するための提案も自由に行ってください)

現在、私のコードは (ほとんどの場合) 動作していますが、入力していない文字がコピーされるというバグがあります。以下は、2 つのテスト実行の (面白い) 結果です。

最初の1つ:

nlightnfotis@crunchbang:~/SoftwareExperiments$ ./reverse
Please input a string:  fotis
DEBUG: The size of the string that we got as input was: 5
DEBUG: The character copied now was s and was at index 4
DEBUG: The character copied now was i and was at index 3
DEBUG: The character copied now was t and was at index 2
DEBUG: The character copied now was o and was at index 1
DEBUG: The character copied now was f and was at index 0
DEBUG: The reversed string is $sitof
The reversed string is $sitof

(注意$)

そして2番目のもの:

nlightnfotis@crunchbang:~/SoftwareExperiments$ ./reverse
Please input a string:  lol
DEBUG: The size of the string that we got as input was: 3
DEBUG: The character copied now was l and was at index 2
DEBUG: The character copied now was o and was at index 1
DEBUG: The character copied now was l and was at index 0
DEBUG: The reversed string is lol
The reversed string is lol

より正確にここに描かれています:

不具合

私よりも知識が豊富で経験豊富な人が、私のコードの何が問題なのかを説明してくれませんか? あるいは、なぜこのイライラするバグに直面しているのかについてのヒントを教えてくれませんか?

4

4 に答える 4

10

ローカル変数を返しています:

char * reverse(char string[]) {    
  char reversed[size + 1];
  ....
  return reversed;
}

スタックに割り当てられたローカル変数reversedは、関数が戻ると存在しなくなりreverseます。したがって、からそれを参照すると、main未定義の動作が発生します。

これを修正するには、次のいずれかを実行できます。

  1. 関数voidを作成し、入力配列を変更します。

  2. 配列reversedを静的として宣言して、その有効期間がプログラムの有効期間に変更されるようにします。

  3. 動的に割り当てる (後で割り当てを解除する)reversed

于 2013-04-19T19:29:21.690 に答える
8

何度も何度も同じエラーが発生します...

私。

char reversed[size + 1];
// ...
return reversed;

関数が戻るとすぐにスコープ外になる自動配列を返しています-未定義の動作。reversedこれを避けるためにstatic変数を作成してください (それが魔法だと思い始める前にキーワードを読んでくださいstatic)。

Ⅱ.

char string[256];
scanf("%s", string);

スペースを含む文字列を入力すると、バッファ オーバーランとバグが発生する可能性があります。これをに変更

fgets(string, sizeof(string), stdin);

III.

char reversed[size + 1];
// ...
reversed[size + 1] = '\0';

別のバッファ オーバーラン。C では、配列は 0 からインデックス付けされます。


良い C の本を読む時間です。

于 2013-04-19T19:32:03.290 に答える
3

codaddict の投稿と H2CO3 の素晴らしい説明に加えて、もう 1 つのエラーがあります。

 char reversed[size + 1];
 reversed[size + 1] = '\0';

これにより、アウト バウンドのインデックスが生成されます。ということsize = 10size +1 =11。char 配列のインデックス値reversed0,1,2,3,...,10. そのため、reversed[11] ご迷惑をおかけいたします。

于 2013-04-19T19:32:24.063 に答える