配列サイズを超えて配列インデックスをオーバーステップすると、GNU / Linuxのような信頼できる真のPOSIXシステムで常にセグメンテーション違反が発生しますか?
アクセスした場所がまだ同じページにある場合は、いいえと思いますが、確認したいと思います。
いいえ、必ずしもそうとは限りません。セグメンテーション違反SIGSEGV
はカーネルによって処理され、無効なメモリアクセスでのみ呼び出されます。
配列は、POSIXと同様にコンパイル時の構成です。一方、セグメンテーション違反は実行時エラーであり、許可されていない(読み取り/書き込み/実行)か、マップされていない(メモリコントローラーが認識していない)仮想メモリで何かを行おうとしたことを示します。どの物理リソースがそれをバックアップすることになっているのか)。その時点で、カーネルはプロセスにシグナルを送信SiGSEGV
し、デフォルトの動作は終了しますが、これはオーバーライドできます。
このようなCコードは、構造体の背後にあるメモリに可変サイズの配列としてアクセスするようにコンパイラに指示することがよくあります。
struct s {
// some other elements
int id; // whatever other elements
char appended_array[0];
};
// ....
struct s* mystruct = malloc(sizeof(struct s) + length_of_array_i_need);
// work with mystruct->appended_array[i]
// at this point mystruct->appended_array[3] is valid C and the compiler will not even issue a warning,
// though if it lies outside of your allowed VM then the kernel will issue a SIGSEGV
配列が特定のインデックスを超えて定義されていないという理由だけで、それは必ずしもそれに続く有効なメモリがないことを意味するわけではありません。