2012-03-06 21 views
-7

これはコーディングサイトの1つです。配列メモリ割り当て

"?"出力が4になるような整数で置き換えます。

int main() 
{ 
    int arr[7]; 
    int b,c,d,a; 
    a=4; 
    printf("%d",arr[?]); 
    return 0; 
} 

私はこれを理解しようとしましたが、その答えは-4であることがわかりました。 もう1つの変数(コードの4行目のint b、c、d、e、aなど)を宣言すると、答えは-5になりました。

コンパイラがどのように動作しているか、メモリ割り当ての理由(負のインデックス)を説明してください。

+5

(配列+ 4つの変数のサイズ)であると予想されているだろう - あなたは目的の結果を与える値を見つけることができるかもしれませんが、コンパイラとアーキテクチャ固有のものであり、未定義の振る舞いに依存します。 –

+0

'arr'を初期化していないので、決して知りません! –

+1

誰でもあなたにこの質問をしましたが、Cプログラミングは分かりません。 – Lundin

答えて

2

最初に注意してください:NEVERこの種の動作に依存するコードは、コンパイラによって異なります。

編集最初の段落は明らかに十分ではないため、範囲外の配列にアクセスすると、の定義されていない動作が発生します。これはコンパイラが選択したプログラムを生成する可能性があることを意味します。ここでは、私はポスターのコンパイラはおそらくを選択したものを説明しているが、結果が偶然4になることもあります。

コンパイラが明らかに(最初の変数はアドレス100で終わると仮定して)次のように変数を配置することを選択した:c

  • 100:a
  • 104:d
  • 108を
  • 112:b
  • 116:arr[0]
  • 120:arr[1]
  • ...
  • 140:arr 116で開始し、その要素(int)の各々のサイズはarr[6]

4バイトであり、arr[-4]は* 116 + 4であります(-4)= 100であり、これはaである。

+0

これは未定義の動作です。コンパイラはこのコードからまったく正常な出力を出すことは保証されておらず、プログラムはクラッシュして焼き付くことが許されています。範囲外の配列にアクセスすることはできません。そのような単純なものです。 – Lundin

+0

私たちが知っている限り、コンパイラはこれもやっていないかもしれません。おそらくメモリ位置arr [-4]にランダムな4つがあり、ここをクリックしただけかもしれません。これも可能でしょうか?しかし、一方で、もしあなたが提案した方法でコンパイラが変数を入れていなければ、例外はありますか?ちょうど興味があることを知っている。ありがとう – Jay

+0

@ Lundin、本当に?これは未定義の動作ですか?同じことを述べている他の10のコメントを読んで、それを推測することはできませんでした!ガイは、起こる可能性が最も高いケースを提示しようとしているだけです。 – jn1kk

1

Cは配列の境界をチェックしません。つまり、使用しているメモリ位置が配列に割り当てられたメモリの一部ではないようにするインデックスを使用できます。

これを実行すると、メモリ内の他の位置にアクセスしています。この例では、以下の4位は、int型の変数bcda

だから、あなたは配列の外と変数の空間にを取得するために予約されています。

とにかく、それはコンパイラ/アーキテクチャに依存することをかもしれないが、私は正しい答えは11これに対する有効な答えはありません

+0

ああ、その他のコメントは本当です。これは本質的に安全ではなく、あなたがCでそれを行うことができる唯一の理由は、あなたがこれをしないと仮定し、プログラムが値をチェックしない(少し速くなる)ためです。このようなコードは決して使用しないでください – SJuan76