1. 導入:なぜCONTROLLED変数の確認が重要なのか
メインフレーム開発において、PL/IのCONTROLLED変数(以下CTL変数)はメモリの動的確保を可能にする強力なツールです。しかし、確保されていない変数を参照しようとすると、システムは容赦なくOC4アベンド(保護例外)を発生させます。これはバッチ処理において致命的な異常終了を招く典型的な原因です。本稿では、実行時の動的なガードとして不可欠な「ALLOCATED関数」を用いた安全なメモリ管理手法を解説します。
2. 基礎知識:CTL変数とメモリの「特異な状態」
CTL変数は、宣言しただけでは「メモリ上の箱(ポインタのようなもの)」が確保されるだけで、実際のデータ領域はメモリ上に存在しません。ALLOCATE文を実行して初めてメモリが接続されます。
現代の言語における「オブジェクトのnullチェック」に近い概念ですが、PL/Iの場合、メモリが未接続の状態であってもコンパイルエラーにはなりません。この「変数はあるが実体がない」という特異な状態を判定するために、ALLOCATED関数が存在します。
3. 実装・解決策:ALLOCATED関数によるガード
処理の中でCTL変数を解放(FREE)する設計の場合、再利用時や終了時の判定で必ずALLOCATED関数を使用します。これにより、二重のFREEによるエラーや、未確保の変数への不正アクセスを未然に防ぐことが可能です。
4. サンプルプログラム
以下は、動的に確保したバッファを安全に制御するためのコード例です。
/ 構造体または変数の宣言 /
DCL MY_BUFFER CHAR(1024) CONTROLLED;
/ メモリ確保のロジック /
IF ^ALLOCATED(MY_BUFFER) THEN DO;
ALLOCATE MY_BUFFER;
/ ここで初期化処理を行う /
END;
/ 安全な参照 /
IF ALLOCATED(MY_BUFFER) THEN DO;
/ 確保されている場合のみ安全に処理を実行 /
MY_BUFFER = ‘DATA_LOADED’;
PUT SKIP LIST(‘データ処理完了: ‘ || MY_BUFFER);
END;
/ 終了時の安全な解放 /
IF ALLOCATED(MY_BUFFER) THEN DO;
FREE MY_BUFFER;
/ 解放後にポインタを無効化する意図で判定を行う /
END;
5. 応用・注意点:現場での陥りやすい罠
現場でよくある失敗は、「ALLOCATED判定を省略してFREE文を投げてしまうこと」です。既に解放済みの変数を再度FREEすると、エラー(条件コードの発生)を引き起こします。
また、サブルーチン間での引数渡しを行う際、呼び出し先でCTL変数が確保されているかどうかを呼び出し元が保証できないケースも多々あります。そのような場合は、必ず呼び出し先でALLOCATED関数によるチェックをルーチン冒頭で行う「ガード節」を設けるようにしてください。この一手間が、深夜のOC4アベンド対応を防ぐ最大の防御策となります。

コメント