現場のエンジニアへ:BASED属性とポインタ管理で「動的ストレージ」を使いこなせ
メインフレームの現場にいると、「レコード長が可変のVSAMファイルを読み込みたい」「メモリを節約するために必要な時だけ領域を確保したい」という場面に必ず遭遇する。COBOLであれば`OCCURS DEPENDING ON`で誤魔化すことも多いが、PL/Iの世界では、ここでBASED属性とポインタ変数を正しく操れるかどうかが、一人前と半人前の分かれ道だ。
今日は、動的メモリ管理の基本と、実務で絶対にやってはいけない「メモリリーク」の罠について、ベテランの視点から解説しよう。
—
1. BASED属性とポインタの基本哲学
PL/IにおけるBASED変数は、それ自体がメモリを確保するわけではない。あくまで「そこにこういう構造のデータがあるはずだ」という型(テンプレート)の定義に過ぎない。
実体を操作するには、`PTR`(ポインタ変数)を定義し、`ADDR`関数でアドレスをセットする、あるいは`ALLOCATE`文でヒープ領域を確保する必要がある。
実践的なサンプルコード
以下は、動的に確保した構造体に対してデータを流し込む典型的なパターンだ。
/i
/ BASED変数とポインタによる動的領域の確保例 /
DCL 1 MY_REC_TEMPLATE BASED(P_MY_REC),
2 REC_ID CHAR(4),
2 DATA_LEN FIXED BIN(15),
2 DATA_BODY CHAR(100) DEF(DATA_LEN); / 実際の長さを制御 /
DCL P_MY_REC PTR; / 領域を指すためのポインタ /
DCL MY_BUFFER_SIZE FIXED BIN(31);
/ 1. 領域の確保(STORAGEクラスの管理) /
/ 必要に応じて動的にメモリを確保する /
ALLOCATE MY_REC_TEMPLATE SET(P_MY_REC);
/ 2. データの操作 /
P_MY_REC->REC_ID = ‘0001’;
P_MY_REC->DATA_LEN = 50;
/ 3. 領域の解放(メモリリーク防止のため必須) /
FREE MY_REC_TEMPLATE;
P_MY_REC = NULL(); / ぶら下がりポインタの防止 /
—
2. VSAMアクセスとポインタ管理の現場的鉄則
大規模バッチ改修で最も怖いのが、ループ内でのメモリ確保だ。VSAMファイルを読み込む際、ポインタを適切に管理しないと、たちまち「S0C4」エラー(ストレージ保護例外)か、最悪の場合は「システム・ストレージ枯渇」によるバッチ異常終了を招く。
「バッファを使い回す」という発想
VSAMアクセスでは、レコード領域を毎回`ALLOCATE`しては`FREE`するのではなく、「最大長で一度だけ確保し、そのアドレスを固定して使い回す」のがメインフレーム流の効率化だ。
/i
/ VSAMレコードを読み込む際のポインタ活用 /
DCL P_VSAM_REC PTR INIT(NULL());
DCL 1 VSAM_AREA BASED(P_VSAM_REC),
2 KEY_FLD CHAR(10),
2 DATA_FLD CHAR(1024);
/ レコード読み込みループ /
DO WHILE(EOF_FLAG = ‘N’);
READ FILE(VSAM_FILE) SET(P_VSAM_REC); / レコードのアドレスが返される /
/ 読み込んだ領域をテンプレートとして参照 /
IF VSAM_AREA.KEY_FLD = ‘TARGET_ID’ THEN DO;
/ 処理ロジック /
END;
END;
—
3. メモリリークを撲滅するための「ONユニット」活用法
実務において最も恐ろしいのは、異常系処理が発生した際に`FREE`文がスキップされ、メモリが食い潰されることだ。`ON CONDITION`や`ON AREA`などを駆使し、異常終了時でも確実にクリーンアップを行う設計を心がけよう。
また、`ALLOCATE`した領域がどこで確保されたか、デバッグ時に追跡できるようにしておくことも重要だ。
- NULLチェックの徹底: ポインタを使用する前には、必ず`IF P_VAR ^= NULL() THEN`を入れろ。これはエンジニアの礼儀だ。
- ぶら下がりポインタの無効化: `FREE`した直後は、必ずポインタに`NULL()`を代入する習慣をつけろ。これだけで、デバッグの難易度は劇的に下がる。
—
最後に:アーキテクトからの助言
PL/Iのポインタ操作は、C言語のポインタとは異なり、コンパイラによる強力な型チェックが働く。これは君たちの味方だ。しかし、メモリ管理の責任は常にプログラマにある。
「なんとなく動いているから良い」というコードは、数年後の改修で必ず君自身の首を絞めることになる。`ALLOCATE`したものは必ず`FREE`する。その単純なルールを、ソースコードの隅々まで徹底してほしい。
今日の解説が、君のバッチ改修の一助となれば幸いだ。もしコードの挙動で悩むことがあれば、いつでも相談に来てくれ。PL/Iは、書き手次第で最高のパフォーマンスを発揮する、歴史に裏打ちされた素晴らしい言語なのだから。
