ポインタのサイズポインタには、++や--演算子が利用できるが、その際、変化する量はデータ型によって異なる。データ型によって占有するサイズが異なるので、++演算子で次のデータに進めたとき、進む量を変化させる必要があるためだ。21-6は具体的なサイズを、sizeof演算子で調べるサンプル・ソースだ。21-6これを実行するとFig.21-7のようになる。Fig.21-7Fig.21-7の最初の3行は簡単に分かるだろう。intのサイズは4バイト、shortのサイズは2バイト、sbyteのサイズは1バイトであることを示している。++演算子で、int型のポインタなら4個進む、というわけだ。問題は後半の3つの数値だろう。これは、すべて同じ内容の3つのstructのサイズを表示しているが、すべて結果が異なっている。これは、StructLayout属性のPack引数の指定により変化したものだ。Pack引数は、メンバの値を配置する単位を指定する。「Pack=4」なら4バイトごとに整列させられるので1バイトで済むsbyteも、4バイト分の場所を占有してしまい、構造体全体では8バイト消費してしまっている。「Pack=1」なら1バイトごとに配列するので、単純にint型(4バイト)とsbyte型(1バイト)で計5バイトという結果になるわけである。ポインタを演算するポインタに使用できるのは++や--演算子だけではない。四則演算や==などの比較演算子も使用できる。21-7はポインタの引き算を、データ型を変えながら実行してみたサンプル・ソースである。21-7これを実行するとFig.21-8のようになる。Fig.21-814行目では、int型のポインタとして引き算している。18行目では全く同じ値を、データ型だけshortへのポインタに変換した上で計算している。22行目では同様にsbyte型で行っている。結果は見てのとおりで、ポインタのサイズを意識した結果、異なる数値が出力されていることが分かるだろう。p1とp2の間には、int型なら3個分、short型なら6個分、sbyte型なら12個分の隙間があるということが示されているわけである。一時変数を容易に確保するstackalloc通常、量の多いデータを扱う場合は配列などを確保するが、配列は移動可能変数であるため、ポインタ利用が面倒になる。スタック上に配列のようなサイズの大きなデータを確保できれば扱いやすい。そのために、C#ではstackallocというキーワードが用意されている。これはC言語のallocaのようなものといえる。21-8はそれを使用した例である。21-8これを実行するとFig.21-9のようになる。Fig.21-9このように、配列でありながらfixedステートメントなしで処理できることが分かると思う。ここでは2つ確認しておきたいことがある。1つは15行目である。このようなポインタを用いた式を使って配列にアクセスすることは、もちろん可能である。1つは、10行目から21行目までのunsafeブロックである。unsafeキーワードはメソッドなどに付けるだけでなく、ブロックを構成する使い方もできる。メソッドの一部だけで「安全でないコード」を使用する場合は、このようなunsafeブロックを使った方が安全だろう。stackallocしたメモリは、そのブロックを抜けると解放されてしまう。ローカルな存在であることに注意が必要だ。stackallocしたメモリへの参照を戻り値で戻すような使い方はできない。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。