Cはアップassemblyと機械コードから1つのステップです。それはあなたのための点検をしません。配列と文字列(配列でもあります)は、どれくらいの長さか、どれだけのメモリが割り当てられているか分かりません。彼らはちょうどメモリの開始点を指しています。
代わりにメモリ境界の外を歩くのはundefined behaviorです。これはCの方法です。「これはエラーですが、教えていただく必要はありません。 array[40][40]
をチェックすると、そのメモリ位置にあったゴミが出ます。それはbuffer overflowとして知られています。 array[0][0]
は、配列が決して初期化されておらず、Cがそれをしないので、あなたにガベージも与えます。
...オペレーティングシステムの可能性があります。これはmemory protectionとして知られています。オペレーティングシステムは、一般的に、プログラムが割り当てられていないメモリにアクセスすることを許可しません。また、保護が向上しています。ただし、メモリの割り当てはきめ細かく行われません。オペレーティングシステムは、20×20の整数配列を割り当てられていることを知らず、プログラムがメモリを大量に割り当てているだけで、おそらくそれ以上の大きさのメモリを確保し、必要に応じてスライスします。
Cの弛緩的態度に役立つさまざまなツールがあります。最も重要なものはValgrindです。これは境界チェックを行うメモリチェッカーであり、さらに多くのことがあります。 Here's a tutorial on it。私は十分にそれをお勧めすることはできません。これは少しわかりにくいかもしれませんが、なぜあなたのプログラムが静かに動作していないのかを伝え、問題をソースに戻します。
多くのCコンパイラには、デフォルトで警告がオンになっていません。ほとんどのコマンドラインコンパイラは-Wall
に応答しますが、それらはすべて警告ではありません(これはCがあなたにうそをつく初めてのことではありません)。いくつかは-Weverything
または--pendantic
を使用します。いくつかのコンパイラは、int array[20][20]
のような静的に初期化されたもののための境界チェックを行います。それは、標準C、物事を成し遂げるためにそのない非常に良い方法を学ぶために便利ですが例えば、clang -Wall
(clangはOS XのデフォルトのCコンパイラです)...
test.c:11:14: warning: array index 40 is past the end of the array (which contains 20 elements)
[-Warray-bounds]
int cc = array[40][40];
^ ~~
test.c:9:5: note: array 'array' declared here
int array[row][cols];
^
を実行しています。標準Cの問題を味わったら、Cを改善するための第三者図書館を見ることをお勧めします。Gnome Libは良いものです。
Cは境界チェックをしません。 – Schwern
ありがとうございます、今私は理解しています、私はより安全にするために手動でバリデーションを行います。 –
@Benこの質問には複数の二重引用符があります。私はちょうど私が特に知っているものを加えました。 –