0

重複の可能性:
「セグメンテーション違反」が発生しないのはなぜですか?

このコードが機能するのはなぜですか?最初の要素が最初の文字のみを保持している場合、残りの文字はどこに保存されますか?そして、これが可能であれば、なぜこの方法を使用しないのですか?

11行目に注意してください:static charc[1]。1つの要素を使用して、必要な数の文字を格納できます。後でそれを指すときに、関数の外でメモリ位置を存続させるために静的を使用します。

#include <stdio.h>

void PutString( const char* pChar ){
   for( ; *pChar != 0; pChar++ )
   {
      putchar( *pChar );
   }
}

char* GetString(){
    static char c[1];
    int i = 0;
    do
    {
        c[i] = getchar();
    }while( c[i++] != '\n' );
    c[i] = '\0';
    return c;
}

void main(){
    PutString( "Enter some text: " );
    char* pChar = GetString();
    PutString( "You typed the following:\n" );
    PutString( pChar );
}
4

5 に答える 5

2

好きな場所に書くことができます:

char *bad = 0xABCDEF00;
bad[0] = 'A';

しかし、そうすべきではありません。上記のコード行が何をするか誰が知っていますか? 最良の場合でも、プログラムはクラッシュします。最悪の場合、メモリが破損していて、かなり後になるまで発見できません。(そして、ソースを突き止めて頑張ってください!)

あなたの特定の質問に答えるために、それは「うまくいきません」。残りの文字は、配列の直後に格納されます。

于 2012-11-04T20:16:24.433 に答える
2

C は配列の境界をチェックしないため、エラーはスローされません。ただし、最初の文字以降の文字は、プログラムによって割り当てられていないメモリに格納されます。文字列が短い場合、これは機能する可能性がありますが、文字列が長すぎると、プロセスがクラッシュするのに十分なメモリが破損します。

于 2012-11-04T20:15:52.463 に答える
1

他のデータ構造を上書きしていないのは、非常に(不)幸運です。配列は間違いなく、必要なだけ多くの文字を格納できません。遅かれ早かれ、黙ってメモリを破損するか (最悪の場合)、プロセスがマップしていないメモリにアクセスしてセグメンテーション違反を起こします。それが機能するという事実は、コンパイラがあなたのc[1]. static char d[1];の後に2 番目の配列を追加してみてcくださいc

于 2012-11-04T20:17:25.767 に答える
1

C++ は、配列の境界チェックを行いません。これはパフォーマンス上の理由によるものです。すべての配列インデックスをチェックして境界外にあるかどうかを確認すると、許容できない実行時オーバーヘッドが発生します。オーバーヘッドを回避することは、常に C++ の設計目標でした。

境界チェックが必要な場合は、std::vector代わりに使用する必要があります。これは、 を介してオプション機能として提供されますstd::vector::at()

于 2012-11-04T20:18:07.787 に答える
1

この場合、動作は定義されていません: コンパイラ / メモリの現在の状態 / ... によると、問題なく動作しているように見えたり、破損した文字が書き込まれたり、セフォールトのためにクラッシュしたりする可能性があります。

Electric Fenceにリンクするか、valgrindで実行すると、実行時にそのようなエラーを見つけるのに役立つ場合があります。

于 2012-11-04T20:18:51.313 に答える