導入
メインフレームの基幹システムで長年運用されているPL/Iプログラムにおいて、最も厄介なバグの一つが「未初期化ポインタ」によるアベンドです。現代の言語と異なり、PL/Iでは変数を宣言しただけではメモリがクリアされず、過去の処理で使用されたデータの残骸が残っている可能性があります。本稿では、POINTER属性の変数を安全に扱うための「暗黙の初期化禁止」という鉄則と、現場で必須となる実装パターンを解説します。
基礎知識
PL/IにおけるPOINTER変数は、メモリ上の「アドレス」を格納するための変数です。しかし、宣言時に値を代入しない場合、その変数にはメモリ上のゴミ(残骸)が入ったままになります。これをそのまま参照すると、意図しないアドレスへアクセスし、S0C4(プロテクション例外)やS0C1(オペレーション例外)などの深刻なシステムエラーを誘発します。いわゆる「ダングリングポインタ」や「不正ポインタ」の状態を回避するためには、宣言と同時に値を確定させることが極めて重要です。
実装/解決策
実務においては、すべてのポインタ宣言に対して、必ず「NULL()」または有効なアドレスを割り当てる規約を徹底してください。特に古いコードベースでは、パフォーマンスを優先して初期化を省略する記述が見受けられますが、現代の保守性においては「明示的な初期化」がリスク管理の要です。静的解析ツールが導入されている環境であれば、初期化漏れを検知するルールを追加し、コンパイル段階でエラーを出す構成にすることをお勧めします。
サンプルプログラム
以下に、安全なポインタ宣言と、メモリ領域への割り当てのテンプレートを示します。
/ 安全なポインタの宣言と利用例 /
DCL P_BASE POINTER INIT(NULL()); / 宣言時に必ずNULLで初期化する /
DCL X_AREA CHAR(100) BASED(P_BASE); / P_BASEに基づく領域定義 /
/ 安全なメモリ割り当てのパターン /
ALLOCATE X_AREA; / 領域を確保 /
/ 処理終了後の解放とポインタの無効化(重要) /
FREE X_AREA;
P_BASE = NULL(); / 解放後にポインタをNULLに戻すことで二重解放を防ぐ /
応用・注意点
現場で陥りやすい罠として、「一度解放したポインタを再利用する」ケースがあります。FREE文を実行しても、ポインタ変数自体には古いアドレスが残ったままです。これを「ワイルドポインタ」と呼びます。必ず上記のサンプルのように、FREEの直後にポインタをNULL()へ戻す処理をセットで行うようにしてください。また、サブルーチン間でのポインタの受け渡しを行う際は、呼び出し先で必ずNULLチェックを行う論理を組み込むことで、より堅牢なシステムを構築することが可能です。

コメント