Next: , Previous: Variables, Up: Data


8.3 人工配列

メモリ内に連続的に配置されている同一型のオブジェクトを表示することが役に立つことがよくあります。 配列の一部や動的にサイズの決定される配列にアクセスするのに、 そこへのポインタしかプログラム内部に存在しないような場合です。

これは、 2項演算子‘@’を使用して、 連続したメモリ範囲を人工配列として参照することで可能です。 ‘@’の左側のオペランドは、 参照したい配列の最初の要素で、 かつ、 1個のオブジェクトでなければなりません。 また、 右側のオペランドは、 その配列の中の参照したい部分の長さでなければなりません。 結果は、 その要素がすべて左側の引数と同型である配列の値です。 第1の要素は左側の引数そのものです。 第2の要素は、 第1の要素を保持するメモリ域の直後のメモリ上から取られます。 これ以降の要素も同様です。 以下に例を示します。 プログラムが以下のようになっているとしましょう。

     int *array = (int *) malloc (len * sizeof (int));

以下を実行することで、 arrayの内容を表示することができます。

     p *array@len

@’の左側のオペランドは、 メモリ上に実在するものでなければなりません。 このような方法で‘@’によって作成された配列の値は、 配列の添字付けの見地からは他の配列と同様に振る舞い、 式の中で使用された場合は強制的にポインタとして扱われます。 人工配列は、 一度表示された後、 値ヒストリ (see Value history) を通して式の中に現れることがよくあります。

人工配列を作成するもう1つの方法は、 キャストを使用することです。 これによって、 ある値を配列として解釈し直します。 この値は、 メモリ上に実在するものでなくてもかまいません。

     (gdb) p/x (short[2])0x12345678
     $1 = {0x1234, 0x5678}

ユーザの便宜を考慮して、 (例えば、 (type[])value’のように) 配列の長さが省略された場合 その値を満たすサイズを (‘sizeof(value)/sizeof(type)’のように) GDBが計算します。

     (gdb) p/x (short[])0x12345678
     $2 = {0x1234, 0x5678}

ときには、 人工配列の機構では十分でないことがあります。 かなり複雑なデータ構造では、 関心のある要素が連続的に並んでいないことがあります。 例えば、 配列の中のポインタの値に関心がある場合です。 このような状況において役に立つ回避策の1つに、 関心のある値のうち最初のものを表示する式の中のカウンタとしてコンビニエンス変数 (see Convenience variables) を使用し、 <RET>キーによってその式を繰り返し実行することです。 例えば、 構造体へのポインタの配列dtabがあり、 個々の構造体のフィールドfvの値に関心があるとしましょう。 以下に、 この場合の例を示します。

     set $i = 0
     p dtab[$i++]->fv
     <RET>
     <RET>
     ...