2016-06-01 6 views
-1

私はこの単純なコードと2次元配列をC言語で試してきましたが、なぜ私のプログラムが失敗しないのか理解できません。なぜ私のコードが範囲外のエラーにならないのですか?

インデックスが範囲外であるとしますか?

#include <stdio.h> 
#include <stdlib.h> 
#define row 20 
#define cols 20 

int main(int argc, char *argv[]) 
{ 
    int x,y; 
    int array[row][cols];  

    int cc = array[40][40]; 

    return 0; 
} 

に関して

+2

Cは境界チェックをしません。 – Schwern

+0

ありがとうございます、今私は理解しています、私はより安全にするために手動でバリデーションを行います。 –

+0

@Benこの質問には複数の二重引用符があります。私はちょうど私が特に知っているものを加えました。 –

答えて

5

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 -Wallclangは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は良いものです。

+0

バインドされていないメモリを変更しようとすると、失敗する可能性が高くなります。ハードウェアは書き込みアクセスを捕まえる可能性が高くなりますが、そうでないとクリティカルなポインタやカウントが壊れてしまった場合、プログラムはクラッシュの間に何かをして正常に動作するように見えます。昨日はうまく動いたときに突然クラッシュする不安定な状態。 – Gilbert

+0

@Gilbert:ほとんどのハードウェアは、そのようなアクセスを確実に検出することも、特定の方法で動作することもありません。 CはPC以外のハードウェアでPCよりもはるかに多く使われています。 – Olaf

+0

Cでプログラムされているほとんどのシステムでは、重量ライブラリや標準ライブラリは利用できません。 – Olaf

関連する問題