配列の範囲外にアクセスするのはどれくらい危険ですか? 質問する

配列の範囲外にアクセスするのはどれくらい危険ですか? 質問する

配列の境界外にアクセスするのはどの程度危険ですか (C の場合)? 配列の外側から読み取る場合 (その後、プログラムの他の部分で使用されているメモリ、またはそれを超えてアクセスすることがわかりました)、または配列の外側のインデックスに値を設定しようとする場合が時々あります。プログラムはクラッシュすることがありますが、予期しない結果のみを返すだけで実行されることもあります。

さて、私が知りたいのは、これが実際どれほど危険なのかということです。プログラムに損害を与えるなら、それほど悪いことではありません。一方、まったく関係のないメモリに何らかの方法でアクセスしたために、プログラム外で何かが壊れる場合は、非常に悪いことだと思います。「何が起きてもおかしくない」、「セグメンテーションは最も軽微な問題かもしれない」、「ハードディスクがピンク色に変色したり、窓の下でユニコーンが歌ったりするかもしれない」など、いろいろなことを読みましたが、どれもいいことですが、実際のところ何が危険なのでしょうか。

私の質問:

  1. 配列の外側から値を読み取ると、プログラム以外に何かが損傷する可能性がありますか? 単に値を見るだけでは何も変わらないと思いますが、たとえば、たまたまアクセスしたファイルの「最後に開いた時間」属性が変更されるでしょうか?
  2. 配列の外側に値を設定すると、プログラム以外に何かが損傷する可能性がありますか? このStack Overflow の質問から、任意のメモリ位置にアクセスすることは可能であり、安全性は保証されないことがわかります。
  3. 私は現在、XCode 内から小さなプログラムを実行しています。これにより、プログラムが自身のメモリ外にアクセスできないように、プログラムの周りに追加の保護が提供されますか? XCode に悪影響を与える可能性がありますか?
  4. 本質的にバグのあるコードを安全に実行する方法について何か推奨事項はありますか?

OSX 10.7、Xcode 4.6 を使用しています。

ベストアンサー1

ISO C 標準 (言語の公式定義) に関する限り、境界外の配列にアクセスすると、「未定義の動作」が発生します。文字通りの意味は次のとおりです。

移植性のない、または誤ったプログラム構造、または誤ったデータの使用時の動作。この国際規格では、これに対しては要件を課していない。

非規範的な注釈では、これについてさらに詳しく説明しています。

起こり得る未定義の動作は、状況を完全に無視して予測できない結果をもたらすものから、環境の特性として文書化された方法で変換またはプログラム実行中に動作すること (診断メッセージの発行の有無にかかわらず)、変換または実行を終了すること (診断メッセージの発行あり) まで多岐にわたります。

それが理論です。現実はどうでしょうか?

「最善」の場合、現在実行中のプログラムが所有するメモリの一部にアクセスするか (これにより、プログラムが誤動作する可能性があります)、現在実行中のプログラムが所有していないメモリの一部にアクセスすることになります (これにより、セグメンテーション エラーなどでプログラムがクラッシュする可能性があります)。または、プログラムが所有しているが読み取り専用としてマークされているメモリに書き込もうとすると、これもおそらくプログラムがクラッシュする原因になります。

これは、プログラムが、同時に実行されているプロセスを相互に保護しようとするオペレーティング システムで実行されていることを前提としています。コードが「ベア メタル」上で実行されている場合、つまり、OS カーネルまたは組み込みシステムの一部である場合、そのような保護はありません。その保護を提供するはずだったのは、不正な動作をするコードです。その場合、損傷の可能性はかなり大きくなり、場合によってはハードウェア (または近くの物や人) に物理的な損傷が生じることもあります。

保護された OS 環境であっても、保護が常に 100% であるとは限りません。たとえば、権限のないプログラムがルート (管理者) アクセスを取得できるようにするオペレーティング システムのバグがあります。通常のユーザー権限であっても、誤動作したプログラムが過剰なリソース (CPU、メモリ、ディスク) を消費し、システム全体がダウンする可能性があります。多くのマルウェア (ウイルスなど) は、バッファ オーバーランを悪用してシステムに不正アクセスします。

(歴史的な例を 1 つ挙げると、コア メモリを搭載した古いシステムでは、ループ内で 1 つのメモリ位置に繰り返しアクセスすると、そのメモリ チャンクが文字通り溶けてしまうことがあると聞いたことがあります。その他の可能性としては、CRT ディスプレイが破損したり、ディスク ドライブの読み取り/書き込みヘッドがドライブ キャビネットの高調波周波数で動いて、テーブルの上を移動して床に落ちたりすることがあります。)

そして、スカイネットのことを常に心配しなければならない。

肝心なのは、故意に何か悪いことをするプログラムを書くことができるのであれば、バグのあるプログラムが偶然に同じことを行う可能性も少なくとも理論的にはあるということです。

実際には、 MacOS X システムで実行されているバグのあるプログラムがクラッシュ以上の深刻な事態を引き起こす可能性はほとんどありません。しかし、バグのあるコードが本当に悪いことをするのを完全に防ぐことは不可能です。

おすすめ記事