1. 10, 0, 10 は安全
  2. 10, 5, 5 は安全
  3. 10, 5, 6 はオーバー
  4. 10, -1, 5 はアンダー
  5. 10, 0, 0 は安全 (何も書かない)
  6. 10, 0, -1 は無効
  7. 10, 10, 0 は境界 (書かない)
コース一覧
コンピューターサイエンス入門:理論編
バッファ範囲チェック

コンピューターサイエンス入門:理論編

2 進数、論理演算、ビット演算、データ構造、計算量、メモリモデルなど、プログラミングの土台となるコンピュータサイエンスの理論知識を学べるコースです。プログラミングを始めたばかりの学習者や、CS の体系的な土台を作りたい現役エンジニアを対象としています。約 13 時間 (1 日 30 分 × 26 日) で 53 レッスンを修了でき、修了後はコードのパフォーマンスや設計判断の根拠を理解した上で実装できるようになります。

1
2進数とビット演算
01. 2進数から10進数への変換5分
02. 10進数から2進数への変換5分
03. ビットAND演算でフラグ判定5分
04. OR / XOR でフラグを操作する5分
05. popcount で 1 のビット数を数える5分
06. シフト演算で 2 倍 / 半分5分
07. 16 進数から 10 進数への変換5分
08. 第 1 章まとめクイズ5分
2
文字コードと真偽値ロジック
01. 文字 → ASCII コード5分
02. コード → 文字5分
03. UTF-8 のバイト長を返す5分
04. AND / OR の真理値表5分
05. NOT / XOR の真理値表5分
06. 含意 (→) を AND/OR/NOT で表現5分
07. ド・モルガンの法則5分
08. 第2章まとめクイズ5分
3
計算量とBig-O
01. forループの実行回数を返す5分
02. 入れ子ループの実行回数5分
03. 線形探索 (O(n))5分
04. 二分探索 (O(log n))5分
05. バブルソート5分
06. 配列の最大と最小5分
07. 累積和で範囲合計5分
08. 第3章まとめクイズ5分
4
データ構造 (基本)
01. スタック (push/pop) を実装する5分
02. キュー (enqueue / dequeue) を実装する5分
03. カッコのバランス判定 (スタック応用)5分
04. set で重複を除去する5分
05. map で出現回数を数える5分
06. 二数の和 (map で O(n))5分
07. アナグラム判定5分
08. 第 4 章クイズ — データ構造 (基本)5分
5
ファイル / メモリ / IO 概念
01. バイト → KB 変換5分
02. ディスクサイズフォーマット5分
03. キャッシュヒット率5分
04. LRU 簡易シミュレーション5分
05. エンディアンの入れ替え (uint32)5分
06. バッファ範囲チェック5分
07. 第5章まとめクイズ5分
6
ネットワークと符号化
01. Base64 エンコード後の長さ計算5分
02. URL エンコード対象文字数5分
03. IPv4 アドレスを 32bit 整数に変換5分
04. 32bit 整数を IPv4 アドレスに変換5分
05. CIDR プレフィックスからネットマスクを作る5分
06. 単純チェックサム5分
07. 第6章まとめクイズ5分
7
設計と DB 基礎
01. 重複データを 1NF に変換 (フラットなリスト化)5分
02. キーで join (map 利用)5分
03. 残高転送のトランザクション風処理5分
04. CAP の availability 模擬5分
05. URL ルーティング5分
06. 疎結合と密結合 — 依存性注入で設計を変える12分
07. コース総まとめクイズ5分

バッファ範囲チェック

用意した箱より長いデータを書き込むと、あふれた分は消えてなくなるわけではありません。隣に置いてあった何かの上に乗ります。書いた側は何も気づかず、乗られた側だけが後で困ります。

はみ出した分は、隣の何かを書き換える

固定長のバッファは、メモリの上に取られた連続した領域です。長さ 10 の箱に 12 バイト書けば、後ろの 2 バイトは箱の外に出ます。そこに別の変数や、領域を管理するための情報が置かれていれば、それが書き換わります。

プレーンテキスト

長さ 10 の箱に 12 バイト書く 番号 0 1 2 3 4 5 6 7 8 9 | 10 11 <------ 箱の中 ----> <-- 外 -->

厄介なのは、書いた瞬間には何も起きないことです。落ちるとしても、書き換えられた値が使われるずっと後で、まったく関係の無さそうな場所が壊れる形になります。ログを見ても書き込んだ側は正常に見えるので、原因までの距離が遠くなります。

範囲外がいつも大声で知らせてくれるとも限りません。切り出しは、頼んだ数に届かなくても黙って短い結果を返します。

Python

data = [0] * 10 print(len(data[8:12])) # 2 4 個頼んだのに 2 個しか返らない print(data[-1]) # 末尾を指す。エラーにはならない

負の番号も同じで、エラーにはならず反対側を指します。この 2 つが、範囲の間違いを静かに通してしまう入口です。

Python や JavaScript の配列は範囲外を弾いてくれますが、Buffer や TypedArray を扱うとき、切り出す範囲を自分で計算するときには、同じ話がそのまま出てきます。

触る場所は、offset から length 個ぶん

どこまで触るのかを、先にはっきりさせます。先頭から offset 番目に length バイト書くなら、実際に触るのは次の範囲です。

Python

buffer_size = 10 offset, length = 8, 4 for i in range(offset, offset + length): print(i, "外" if i >= buffer_size else "内") # 8 内 / 9 内 / 10 外 / 11 外

最後に触るのは offset + length - 1 番です。箱の中にある番号は 0 から buffer_size - 1 までなので、この 2 つを見比べれば収まるかどうかが決まります。ここで 1 ずれると、ぴったり収まる書き込みを断ってしまうか、1 バイトだけはみ出す書き込みを通してしまうかのどちらかになります。

解説

1 だけずれる間違いは off-by-one と呼ばれます。境目を扱う関数は、ぴったり収まるときと 1 だけはみ出すときの両方を必ずテストします。

通信で受け取ったデータを扱うときは、この計算の材料が外から来ます。ヘッダに書かれた長さをそのまま信じて本文を読み進めると、届いた分より先まで触ることになります。長さは、受け取った実際の大きさと突き合わせてから使います。

書く前に確かめる

あふれてから気づく方法はありません。書き込む前に確かめます。材料は、箱の大きさ、書き始める位置、書く長さの 3 つだけです。

見落としやすいのが負の数です。位置や長さに -1 が入ってくると、大小の比較だけをすり抜けます。長さがマイナスというのは意味を持たないので、比較に入る前に弾きます。逆に長さ 0 は何も触らないので、位置さえ箱の内側なら通してかまいません。

同じ判定が標準ライブラリに用意されていることもあります。Java の Objects.checkFromIndexSize や、C++ の std::span がそれです。用意されているなら、自分で書く前にそちらを使います。判定を自分で書くのは、その形が手の中にあるからこそ、ライブラリが何を守っているのかが読めるようになるためです。

要件

  1. isSafeWrite という名前の関数を実装すること
  2. offset と length が 0 以上であることを確認すること
  3. offset + length <= bufferSize なら true を返すこと

入出力例

isSafeWrite(10, 0, 10) → true isSafeWrite(10, 5, 5) → true isSafeWrite(10, 5, 6) → false isSafeWrite(10, -1, 5) → false isSafeWrite(10, 0, 0) → true isSafeWrite(10, 0, -1) → false isSafeWrite(10, 10, 0) → true

ヒント

負の値のチェックを最初に入れる

比較は < ではなく <= を使う

true / false を boolean で返す

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • 第5章まとめクイズ

    バイト・KB変換、キャッシュ、LRU、エンディアン、バッファ範囲を総復習する4択クイズ

  • Base64 エンコード後の長さ計算

    バイト列を Base64 エンコードしたときの文字数を、入力長から数式で求める関数を作ります。

  • 重複データを 1NF に変換 (フラットなリスト化)

    1 セルに複数値が詰め込まれた CSV 風データを、1 行 = 1 値にフラット化する第一正規形(1NF)の変換を実装します。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • メモリプログラムとデータを一時保持する高速領域
  • 変数データに名前をつけて参照する仕組み
  • JavaScriptWeb で動的な振る舞いを担う言語
  • 配列サイズ固定の同型データの集まり
  • 関数処理に名前を付けて再利用できる単位
  • テストバグを見つける工程
  • 標準ライブラリPythonに同梱の公式モジュール群
main.py
学習モード
エディタを読み込んでいます

メモ

バッファ範囲チェック

⌘S で保存