ポインタ概論 その4

 
さて、前回までの3回でポインタ変数に対する基本的な説明は終わるわけですが、では、このポインタ変数・・・、実際にどう使えばいいのか。
 
というわけで、ポインタ変数によって出来る応用例として、例えば、自己参照構造体や、参照権の共有というものが挙げられます。
どっちも、構造体のメンバ変数としてポインタ変数を採用することで可能なわけで、一番分かりやすい応用例だと思います。
 
自己参照構造体とは、メンバ変数として、自身の構造体へのポインタ変数を持つ構造体を指します。
通常、構造体 struct T のメンバ変数として、 struct T 型の変数を持つことは出来ません。
構造体に限らず基本的にC言語処理系は上から下へ処理をしていくため、まだ struct T の定義の途中にも関わらず
メンバ変数の段階で struct T がきても、定義が途中であるため、要するにサイズが決定できないわけですね。
 
その点、struct T * であれば、常にポインタ変数のサイズとして決定されるという寸法です。
 
当然といえば当然ですが、struct T *型メンバ変数は、どこからの struct T 構造体変数のポインタを値として持つこととなります。
もちろん、この状況は、自己参照構造体でない、一般の型のポインタ変数をメンバ変数として持つ場合でも言えることです。
 
このとき、どういうことが起こるかを突き詰めるため、参照権という考え方を導入していくことになります。
 
定義から述べれば、ここでいう参照権とは、「* オペレータを使用して有効な記憶領域を参照することの出来る権利」を指します。
当然、有効な記憶領域に対するポインタを持つポインタ変数はこの参照権を持つ変数と言えます。
 
当然、参照権を持たないポインタ変数というものは存在し、その代表例が、NULL を値としてもつポインタ変数です。
理想を言えば、それ以外の全てのポインタ変数は参照権を持つと言えます。
 
ポインタ変数 p にポインタ変数 q を代入するということの意味は、この参照権という言葉を使うならば、
「p は q の参照権を共有する」という解釈をすることができます。
 
通常の変数では、この状況は起こりえません。つまり、ポインタ変数の一番の特徴であり、最も頻度の高い使い道といえます。
 
メンバ変数としてポインタ変数を持つ構造体は、このように、構造体における通常の代入オペレータにより、
自動的に参照権の共有を行います。
 
この状況から言えることは、自己参照構造体においても、当然ながら同様の現象が起こるということです。
そして、一番の問題がその参照権を共有する参照先の記憶領域が、ヒープ領域である場合です。
 
当然、この場合、C 言語ならば free() 関数を ただ1度だけ実行しなくてはならないのですが、
参照権を共有している場合、その複数のポインタ変数のうちの1つを free() した瞬間、そのポインタ変数を含め、
全ての参照権を共有していたポインタ変数が、NULL ポインタでないにもかかわらず事実上参照権を持たないこととなってしまいます。
 
この状況を打開すること・・・、これが、ポインタ変数を構造体のメンバ変数として採用していく際に必要となる最優先事項となります。
そこで、次回からの話を進める上において、もう1つのポインタ変数に関する概念である、所有権を定義しておきます。
 
所有権とは、「有効な記憶領域を解放することの出来る権利」を指します。
 
したがって、所有権を持つポインタ変数は定義上、参照権も持つこととなります。
 
続く
 
 
 
カテゴリー: コンピュータとインターネット パーマリンク

コメントを残す