コンピュータが「計算できない」状態とは?オーバーフローの意味と種類を解説

オーバーフロー

「1バイトで表せる最大値は255なのに、255+1を計算したら0になった」――こんな不思議な現象を聞いたことはないでしょうか。これがオーバーフローです。

オーバーフローはITの世界で頻出する用語であり、プログラムのバグやセキュリティ攻撃の根本原因になることも珍しくありません。この記事では意味・種類・セキュリティリスクまでまとめて解説します。

  • オーバーフローとは何か(語源と基本の意味)
  • コンピュータが扱える数値に「上限」がある理由
  • 整数・バッファ・スタック、3種類の違い
  • アンダーフローとの違い
  • バッファオーバーフロー攻撃とセキュリティリスク
  • オーバーフローを防ぐ基本的な考え方

オーバーフローとは何か

語源と基本的な意味

オーバーフロー(overflow)とは、英語で「あふれ出る」という意味の言葉です。ITの分野では、コンピュータが扱える数値や領域の上限を超えてしまう現象を指します。

水の入ったコップに水を注ぎすぎるとこぼれるように、データがコンピュータ内の「入れ物」の容量を超えるとオーバーフローが発生します。

コンピュータが扱える数値には「上限」がある

コンピュータはすべてのデータを0と1のビット列で表します。そのため、使えるビット数によって表現できる数値の範囲が決まります。

データ型 ビット数 表現できる範囲(符号なし)
1バイト整数 8ビット 0 〜 255
2バイト整数 16ビット 0 〜 65,535
4バイト整数 32ビット 0 〜 約42億
8バイト整数 64ビット 0 〜 約1.8京京

たとえば1バイト(8ビット)の符号なし整数型に「255 + 1 = 256」を格納しようとすると、256は表現できないため、ビットがひと回りして0になります。これがオーバーフローです。

ポイント

オーバーフローとは「入れ物の上限を超えたデータが正しく格納できなくなる現象」。コンピュータは数値を有限のビット数で表すため、必ず上限が存在する。

オーバーフローが起きるとどうなるか

計算結果がおかしくなる(具体例)

最もわかりやすい影響が「計算結果の崩壊」です。8ビット符号なし整数で「200 + 100」を計算すると、本来は300ですが、255を超えた分がひと回りして44になります。

実際にこの問題が大規模な障害を引き起こした事例があります。1996年のアリアン5ロケットの打ち上げ失敗は、64ビット浮動小数点数を16ビット整数型へ変換した際のオーバーフローが原因のひとつとされています。

プログラムがクラッシュする

言語や処理系によっては、オーバーフローが発生した時点で例外(エラー)を投げてプログラムを停止させるものもあります。C言語のような低レベル言語では例外を投げずに誤った値のまま処理が続くことが多く、これがバグやセキュリティ脆弱性につながります。

オーバーフローの3つの種類

オーバーフローは発生する場所や状況によって大きく3種類に分かれます。それぞれの違いを整理しておきましょう。

種類 発生場所 主な影響
整数オーバーフロー 数値演算(変数) 計算結果の誤り・異常値
バッファオーバーフロー メモリ上のバッファ領域 隣接メモリの破壊・セキュリティ攻撃
スタックオーバーフロー コールスタック プログラムのクラッシュ

整数オーバーフロー

整数型変数に格納できる最大値を超える演算を行ったときに発生するオーバーフローです。冒頭の「255 + 1 = 0」がこれにあたります。

そのままプログラムが動き続けるため気づきにくく、後になって「なぜかカウンターが0に戻る」「金額の合計がマイナスになる」といった不可解なバグとして現れることがあります。

バッファオーバーフロー

バッファ(データを一時的に保持するメモリ領域)に対して、割り当てたサイズを超えるデータを書き込もうとしたときに発生します。あふれたデータは隣接するメモリ領域に書き込まれ、別のデータや処理の制御情報を上書きしてしまいます。

セキュリティ上の脅威として特に重要で、攻撃者がこの仕組みを悪用して任意のコードを実行させる「バッファオーバーフロー攻撃」に発展するケースがあります(詳しくは後述)。

スタックオーバーフロー

プログラムが関数を呼び出すとき、呼び出し元の情報(戻り先アドレスなど)はコールスタックと呼ばれるメモリ領域に積み重ねられます。再帰呼び出しが無限に繰り返されるなどしてコールスタックの上限を超えると、スタックオーバーフローが起きてプログラムは強制終了します。

プログラミング学習中に「再帰関数の終了条件を書き忘れたらクラッシュした」という経験をした方は、まさにスタックオーバーフローに遭遇しています。

用語メモ

バッファオーバーフロー(Buffer Overflow)とスタックオーバーフロー(Stack Overflow)は名前が似ていますが別の現象です。バッファオーバーフローはメモリへのデータ書き込み問題、スタックオーバーフローはコールスタックの積み過ぎによる問題です。

オーバーフローとアンダーフローの違い

オーバーフローと対になる概念がアンダーフロー(underflow)です。こちらは「上限を超える」ではなく「下限を下回る」現象を指します。

用語 意味 発生例
オーバーフロー 表現できる最大値を超える 255 + 1 → 0(8ビット整数)
アンダーフロー 表現できる最小値を下回る 浮動小数点数で値が0になる

アンダーフローは特に浮動小数点数(小数を扱うデータ型)で発生しやすく、値の絶対値が非常に小さくなったとき(小数点以下の0が増えすぎたとき)に0として扱われてしまいます。除算や乗算の結果が大きく狂う原因になります。

バッファオーバーフロー攻撃とセキュリティリスク

バッファオーバーフローはセキュリティ上の脆弱性として特に危険です。攻撃者はこの仕組みを意図的に悪用し、バッファオーバーフロー攻撃を仕掛けます。

攻撃の仕組み

プログラムが外部からデータを受け取ってメモリに保存する際、そのサイズチェックが不十分だと、攻撃者は意図的に大量のデータを送り込めます。あふれたデータで「関数の戻り先アドレス」を書き換えることで、攻撃者が用意した悪意のあるコードを実行させることが可能になります。

1

過大なデータを送信

攻撃者がバッファサイズを超えるデータをプログラムに送りつける

2

隣接メモリが上書きされる

あふれたデータが戻り先アドレスなど重要な情報を破壊する

3

任意のコードが実行される

書き換えたアドレスに攻撃用コードを仕込み、システムを乗っ取る

被害と影響

バッファオーバーフロー攻撃が成功すると以下のような被害が発生します。

  • 管理者権限の奪取(システムの完全掌握)
  • 機密情報の窃取
  • マルウェアの埋め込み
  • DoS攻撃の踏み台化
  • システムの強制停止

C言語やC++はメモリ管理を開発者に委ねる設計のため、バッファオーバーフローの脆弱性が生まれやすい代表的な言語です。一方、JavaやPythonなどの高水準言語はランタイムが境界チェックを行うため、比較的リスクが低いとされています。

オーバーフローを防ぐための基本的な考え方

オーバーフローを完全にゼロにするのは難しいですが、以下の基本的な対策で大幅にリスクを下げられます。

適切なデータ型を選ぶ

扱うデータの最大値を見積もり、十分なビット数のデータ型を選択する。金額や個数など大きくなりうる値には64ビット整数型を使う。

入力値を必ず検証する

外部から受け取るデータはサイズと型を検証してから処理する。バッファに書き込む前に「受け取ったデータがバッファサイズ以内か」を確認する。

安全なライブラリ・言語を使う

C言語の古い関数(gets、strcpy など)は境界チェックがなく危険。安全な代替関数(fgets、strncpy)や、メモリ管理を自動化する言語を選ぶ。

再帰の終了条件を必ず設ける

再帰関数はかならず終了条件を定義し、深すぎる再帰が起きないよう設計する。スタックオーバーフローの防止に直結する。

主要プログラミング言語でのオーバーフローの扱い

オーバーフローが発生したときの挙動は、使用するプログラミング言語によって大きく異なります。言語選択の際の参考にしてください。

言語 整数オーバーフローの挙動 安全性
C / C++ 未定義動作(ラップアラウンドまたはクラッシュ) 低(開発者が管理)
Java ラップアラウンド(例外なし・エラーにならない) 中(バッファOFは防止)
Python 自動的に多倍長整数へ拡張(OFしない) 高(自動管理)
Rust デバッグ時はパニック、リリース時はラップアラウンド 高(コンパイル時に検出)
Swift 実行時エラー(オーバーフロー演算子で意図的に許可も可) 高(デフォルトで検出)

Pythonは整数型に上限がなく、計算結果が大きくなるにつれて自動的にメモリを拡張するため、整数オーバーフローが原理的に発生しません。一方、C言語はパフォーマンスを優先した設計のため、境界チェックは開発者の責任です。RustはC言語並みの速度を持ちながら、コンパイル時のチェックでメモリ安全性を高めた比較的新しい言語として注目されています。

オーバーフローに関するよくある質問

「Stack Overflow(スタックオーバーフロー)」というサイトは何ですか?

Stack Overflowは、世界最大級のプログラミングQ&Aサイトです。開発者がコードの疑問を投稿し、コミュニティが回答する仕組みで、2008年の開設以来エンジニアにとって欠かせない情報源となっています。名前はプログラミング用語のスタックオーバーフローに由来しています。IT用語のスタックオーバーフローとは別物なので混同しないよう注意しましょう。

オーバーフローとバグの違いは何ですか?

バグはプログラムの誤り全般を指す広い言葉です。オーバーフローはバグの原因のひとつであり、「オーバーフローが起きてバグが発生した」という関係になります。オーバーフロー自体は現象であり、それがプログラムの誤動作(バグ)を引き起こすと理解するのが正確です。

2038年問題はオーバーフローと関係がありますか?

はい、密接に関係しています。Unix系システムでは時刻を「1970年1月1日からの経過秒数」を32ビット符号付き整数で管理しています。この値は2038年1月19日に32ビット整数の最大値(約21億)を超えてオーバーフローし、時刻が1901年に戻る可能性があります。これがY2K問題に続く「2038年問題」です。現在は64ビット整数への移行が進んでいます。

CSSのoverflowプロパティとITのオーバーフローは同じ意味ですか?

概念は同じ「あふれ」ですが、対象が異なります。CSSのoverflowプロパティはWebページのレイアウトにおいて、コンテンツがコンテナ(ボックス領域)からはみ出したときの表示方法を制御するものです(hidden/scroll/autoなど)。ITのオーバーフローはコンピュータのメモリや数値演算の問題を指します。どちらも「入れ物からあふれる」という共通の概念を持ちます。

まとめ

オーバーフローとは、コンピュータが扱える数値や領域の上限を超えてしまう現象です。

この記事のまとめ

  • オーバーフローとは「入れ物の上限を超えてデータが正しく格納できなくなる現象」
  • 整数オーバーフロー・バッファオーバーフロー・スタックオーバーフローの3種類がある
  • 対になる概念がアンダーフロー(下限を下回る現象)
  • バッファオーバーフローはセキュリティ攻撃に悪用される危険な脆弱性
  • 対策の基本は「適切なデータ型の選択」「入力値の検証」「安全な関数の使用」
  • 言語によって挙動は異なり、PythonはOFしない・Rustはコンパイル時に検出

関連用語としてアンダーフローバッファも合わせて理解すると、コンピュータのメモリ管理への理解がより深まります。