ヒープ記憶域の問題

図 1 は、ヒープ記憶域の誤用に関連して起こる可能性のある問題を示しています。

図 1. ヒープ記憶域の誤用
 *..1....+....2....+....3....+....4....+....5....+....6....+....7...+....
 *-----------------------------------------------------------------*
 * ヒープ記憶域の誤用                                              *
 *-----------------------------------------------------------------*
D Fld1            S             25A    BASED(Ptr1)
D Ptr1            S               *

 /FREE
    Ptr1 = %ALLOC(25);
    DEALLOC Ptr1;
 
  // この時点以降は、基底ポインター Ptr1 は割り振られた記憶域を
  // 指さなくなるので、Fld1 にアクセスすることはできません。
 
    SomePgm();
 
  // 'SomePgm' への以前の呼び出し時に、複数の記憶域の割り振りが行なわれた
  // 可能性があります。
  // いずれにしても、記憶域の 25 バイトに 'a' が埋め込まれているため、
  // 以下の割り振りを行なうのは非常に危険です。
  // この記憶域が現在何に使用されているのかを知ることはできません。
 
    Fld1 = *ALL'a';
 /END-FREE
同様に、以下のような場合にもエラーが発生する可能性があります。
  • 再割り振りまたは割り振り解除が行われる前にポインターがコピーされている場合には、 同様のエラーが生じる可能性があります。 ポインターを割り振り済み記憶域にコピーする際には十分に注意して、 記憶域の割り振り解除あるいは再割り振りが行われた後でポインターを使用しないようにする必要があります。
  • ヒープ記憶域へのポインターがコピーされると、 記憶域の割り振り解除または再割り振りにそのコピーが使用できます。 この場合、元のポインターに新しい値を設定するまでは、このポインターを使用できません。
  • ヒープ記憶域へのポインターがパラメーターとして渡されると、 呼び出された側は、記憶域の割り振り解除または再割り振りを行うことができます。 呼び出しが戻った後で、ポインターにアクセスしようとすると、問題が生じる場合があります。
  • ヒープ記憶域へのポインターが *INZSR に設定されていると、 その後でポインターの RESET を行うと、ポインターが、割り振られていない記憶域に設定される可能性があります。
  • ヒープ記憶域へのポインターが (消去されたり、例えば ALLOC 命令によって 新しいポインターに設定されることによって) 失われた場合には、別の問題が生じる場合があります。 ポインターが失われた後では、このポインターが指していた記憶域を解放することはできません。 この記憶域がアドレス不可能になったことをシステムが認識していないため、 この記憶域を割り振ることはできません。

    この記憶域が解放されるのは、活動化グループが終了した後です。