5

負のインデックスを使用するのは単なる運だと思います。しかし、好奇心から私はこれを試しました。array[0]; を宣言できることは知っています。malloc(0); と同じです。合法です。しかし、どうして配列 [0] に値を格納できるのでしょうか?

#include <stdio.h>
#include <conio.h>
int main(void)
{
    int i;
    int array[0];
    array[0] = 5;
        printf("%d\n",array[0]);
    getch();
}
4

5 に答える 5

4

このような0サイズの配列は、標準 C では制約違反です。コンパイラは、診断を行わずにこれを回避することはできません。それでも何もわからない場合は、コンパイラ ベンダーが C 方言に追加した拡張機能に違いありません。

そのような拡張機能に依存しないでください。

size で配列を宣言するかどうかに関係なく0、C では、配列またはポインター アクセスの境界チェックが課されていません。ただし、コンパイル時に境界の超過がわかっている場合は、最新の優れたコンパイラでも警告が表示されます。

于 2012-09-27T11:59:13.820 に答える
0

未定義または他の何かによって使用されているメモリ空間にアクセスしています。malloc を使用するまで、配列がどこに存在するかわからないため、このコードは最終的に何かを台無しにします。サイズ 0 の配列を作成しました。C では、アドレスを指定すると、どこにでも好きなように書き込むことができます。オペレーティング システムが干渉しないようにします。「配列」は配列へのポインタであり、任意の値を持ちます。コンパイラは、配列のゼロ番目の要素を使用しているため、そのメモリ空間を予約する必要があることを認識していません。

于 2012-09-27T11:47:20.213 に答える
0

C は、(可能な場合) 自分が何をしているかを知っていると想定します。長さゼロの配列にはまだアドレスがあります (ただし、そのアドレスは他のサイズのものと簡単に共有できます)。その配列にインデックスを付けると、使用しているメモリの場所を変更するだけで、最終的にアドレスを使用する他のものを気にする必要がなくなります。また、書き込みによって、巨大な (そしてデバッグが困難な) 問題を簡単に引き起こす可能性があります。 .

于 2012-09-27T11:48:22.137 に答える
0
int array[0]; 

is Invalid C code.非標準準拠です。コンパイラ固有の拡張機能を使用しているため、コードは正常にコンパイルされます。

参照:
C99 標準: 6.7.5.2 配列宣言子
Para 1:

オプションの型修飾子とキーワード static に加えて、[ と ] で式または を区切ることができ*ます。それらが式 (配列のサイズを指定する) を区切る場合、式は整数型を持つ必要があります。式が定数式の場合、値は 0 よりも大きくなければなりません。要素の型は、不完全型または関数型であってはなりません。オプションの型修飾子とキーワード static は、配列型を持つ関数パラメーターの宣言にのみ表示され、その後、最も外側の配列型の派生にのみ表示されます。


が機能しているように見えるのはなぜですか?

コンパイラの実装で長さゼロの配列が許可されていると仮定します。

array[0] = 5; 

このコード ステートメントはUndefined Behaviorを引き起こすため、引き続き機能します。
配列が所有していないメモリ領域に書き込み、割り当てられたメモリの境界を上書きします。幸いなことに、メモリはおそらく他のエンティティによって使用されていないため、機能します。技術的には、これはまだ未定義の動作です。

于 2012-09-27T12:07:15.607 に答える