0

これは私のコードです:

char *genWord(int wordLen){
    char array[wordLen + 1];
    char *word;
    int i;

    for(i = 0; i <= wordLen; i++){
        array[i] = 'a';
    }

    array[wordLen] = '\0';

    //Test1 printf
    printf("%s \n", array);

    word = array;

    //Test 2
    printf("%s \n", word);

    return word;
}

main(){
    char *word;
    int wordLen = 10;

    word = (char *)genWord(wordLen);

    //Test 3
    printf("%s", word);       
}

これは、Linux gccで実行される3(同じプログラム)の出力です。

1位:

aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaT��aaaaa

2番目:

aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaa�ƃ�aaaaa 

3位:

aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaaaaaaaaaaa 
aaaaaaaaaaaa����aaaaa   

何が悪いのか、さらに悪いことに、実行ごとに異なる出力を取得する方法を想像できませんか?可変単語は文字列の一部にゴミを入れることはできませんよね?!

4

2 に答える 2

4

スタックに割り当てられたメモリへの参照を返します(array)。

このメモリは、から戻るときに自動的に解放されgenWord()ます。

そのため、返される参照は有効なメモリを参照しなくなります。

この問題を修正するには

  • genWord()動的に(内部で genWord())必要なメモリを割り当てるか、
  • または、必要なデータをコピーする先genWord()(の外部から)にバッファを渡します。genWord()

補足として:いわゆるCストリングはゼロで終了します。つまり、文字列を表す文字配列は、最後の(終了)要素としてNUL文字(10進数)を取ります(この位置は、コードではなく、の値によってインデックス付けされます)。0iwordLen

関数のファミリーは、文字列の「長さ」を決定するためにstr*、基本的に終了に依存しています。0

したがって、文字列を1文字ずつ作成する場合は、完了時に最後の要素の後にgenWord()終了を追加してください。0代わりに(より高価ですが、より便利ですが)、0使用する前にバッファ全体をsで初期化するだけです。

于 2012-12-16T14:20:24.563 に答える
3

呼び出しから戻った後に割り当てられることが保証されていないローカルアドレスを返しています。したがって、これは未定義の動作です。

するとword = array、配列のローカルアドレスが変数にコピーされwordます。返された後、呼び出し元の関数には、関数内のローカル アドレスであるアドレスがあります。ただし、関数が返された後、アドレスは無効になり、他の目的に割り当てられたり、上書きされたりする可能性があります。

word = strdup (array);ORを行う

word = malloc (sizeof (char) * (strlen (array) + 1));
strcpy (word, array);
return word;
于 2012-12-16T14:31:48.980 に答える