メインフレームの世界へようこそ。COBOLやJavaでバリバリ開発してきたあなたにとって、PL/Iは少し「古風で気難しい友人」に見えるかもしれません。でも大丈夫、この言語は非常に論理的で、一度コツを掴めばこれほど頼りになる相棒はいません。
今日は、PL/Iのメモリ管理における「魔法の杖」、BASED変数とポインタについて、現場の視点から紐解いていきましょう。
—
1. なぜ「BASED」が必要なのか?
Javaなら `new` を使ってインスタンスを作りますよね。COBOLなら `WORKING-STORAGE` で領域を静的に確保するのが基本です。しかし、PL/Iの `BASED` は、それらとは少し違う「自由な場所」を扱うための仕組みです。
簡単に言うと、「BASED変数は、それ自体では実体を持たない『型枠』に過ぎない」と考えてください。
- 型枠(BASED変数): 「こういう形のデータが欲しい」という設計図。
- ポインタ: その型枠を「どこに置くか」を指定する住所(メモリアドレス)。
BASED変数を宣言しただけでは、メモリは一切消費されません。ここがCOBOLとの大きな違いです。「ここに家を建てたい(ALLOCATE)」と命令した瞬間に、ポインタがその場所を指し示し、初めてデータが息を吹き込みます。
2. 基本の書き方:型枠とポインタのコンビネーション
実際のコードを見てみましょう。複雑な構文に見えますが、構造はとてもシンプルです。
1
/ ポインタ変数(住所)の宣言 /
DCL P_REC POINTER;
/ BASED変数(型枠)の宣言 /
DCL 1 MY_DATA BASED(P_REC),
2 ID FIXED BIN(15),
2 NAME CHAR(20);
/ メモリの確保と利用 /
ALLOCATE MY_DATA; / ここで初めてメモリが確保され、P_RECに住所が入る /
ID = 101;
NAME = ‘IBM_MAIN’;
/ 後処理:メモリの解放 /
FREE MY_DATA; / 使い終わったら必ず解放。これを忘れるとメモリリークの温床に /
現場で役立つポイント:なぜ `POINTER` を明示するのか?
`DCL MY_DATA BASED(P_REC)` と書くことで、「この変数は常に `P_REC` が指す場所にある」とコンパイラに伝えています。もし複数の場所で同じ構造を使いたければ、`ALLOCATE MY_DATA SET(P_NEXT);` のように明示的にアドレスを指定することも可能です。この柔軟さが、PL/Iが長年基幹システムで重宝されてきた理由の一つです。
3. 初学者がハマりやすい「落とし穴」
PL/Iのメモリ管理には、モダンな言語にはない「職人的な注意点」があります。
① 「FREE」した後のポインタには要注意
`FREE` を実行すると、確保した領域はシステムに返却されます。しかし、ポインタ変数(`P_REC`)の中身は空になりません。 ゴミアドレスが残ったままになるのです。
もし解放後にそのポインタを参照し続けたら…そう、システム異常終了(ABEND)への特急券です。解放直後には `P_REC = NULL();` としておくのが、熟練アーキテクトの嗜みです。
② 領域の断片化(フラグメンテーション)
大量の `ALLOCATE` と `FREE` を繰り返すと、メモリ上に小さな隙間が散らばります。メインフレームの限られたリソースの中で、長時間稼働するオンラインプログラムの場合、この管理を怠るとメモリ枯渇を引き起こすことがあります。「必要な時に確保し、不要になったらすぐ捨てる」というサイクルを意識してください。
4. 最後に:怖がらなくて大丈夫です
PL/IのポインタとBASED変数は、メモリを直接制御できる強力なツールです。Javaのガベージコレクションに慣れていると「自分で解放するの?」と不安になるかもしれません。しかし、これは言い換えれば「プログラムのライフサイクルを完全にコントロールできる」という特権でもあります。
まずは小さなバッチプログラムで、リスト構造や動的なテーブル作成を試してみてください。一つずつメモリを確保し、繋ぎ、解放する。そのプロセスが見えてくると、PL/Iが隠し持っている「計算機を極限まで使い倒す快感」が少しずつ分かってくるはずです。
もし分からないことがあれば、またいつでも聞いてくださいね。メインフレームの世界で、一緒に楽しく学びを深めていきましょう。
