3.3 動的領域管理

番号 以下をクリックすると,該当箇所にジャンプします
(1) 考え方
(2) 初期化
(3) 領域の確保
(4) 領域の返却

(1)考え方


CやC++では,calloc関数,free関数を使って,
領域の確保・開放を行い,
ポインタでデータを参照することがよく行われますが,

C#では,安全なプログラミングの観点から
ポインタの使用は推奨されていません。

したがって,次のように
あえてUnsafeを指定することになっています。

  unsafe
  {
    char* p=stackalloc char[256];
    for (int i=0; i<256;i++) *(p+i)=(char)i;
    int* values = stackalloc int[20];
    int* a= & values[1];
    int* b= & values[15];
    MessageBox.Show
      (string.Format(" a - b = {0} \n b - a = {1}",a-b,b-a));
  }

しかし,リスト構造等を扱うとき,頻繁にデータ確保,開放
を行う必要があります。

一方,バグが潜む多くは,領域確保・開放の部分です。
ですから,領域確保・開放をシステム任せにしないで,
自分が制御できる範囲内で領域確保・開放を行いたいものです。

このようなとき,配列領域を分割して,動的に管理します。


番号 以下をクリックすると,該当箇所にジャンプします
(1) 考え方
(2) 初期化
(3) 領域の確保
(4) 領域の返却

(2)初期化


最初,次のように各要素のリストを作っておきます。

   

[プログラム処理](空ポインタを-1とする)

  public struct ElementData
  {
    public long 番号;
    public string 氏名;
    public int 点数;
  }
  public struct ElementSet
  {
    public ElementData Element;
    public long Next;
  }
  public ElementSet[] DataArea = new ElementSet[500];
  public long ErasedP; // 未使用領域の先頭領域

  private void 初期化( )
  {
   for(int i=0;i<DataArea.Length-1;i++) DataArea[i].Next=i+1;
   DataArea[DataArea.Length-1].Next=-1;
    ErasedP=0;
  }



番号 以下をクリックすると,該当箇所にジャンプします
(1) 考え方
(2) 初期化
(3) 領域の確保
(4) 領域の返却

(3)領域の確保


最初,次のように各要素のリストを作っておきます。

未使用ポインタが指している要素を使うものとします。
すなわち,以下の手順で処理します。

 @)未使用ポインタを関数値とする
 A)未使用ポインタが指しているポインタを未使用ポインタとする。

    

[プログラム例]

  private long GetArea( )
  {
    long R = ErasedP;
    ErasedP = DataArea[ErasedP].Next;
    return R;
   }

番号 以下をクリックすると,該当箇所にジャンプします
(1) 考え方
(2) 初期化
(3) 領域の確保
(4) 領域の返却

(4)領域の返却


領域の返却とは,指定された要素を未使用領域の管理下に
戻すことです。すなわち,

 @)未使用ポインタの内容を返却領域のポインタとする。
 A)未使用ポインタを返却領域へのポインタとする。

の手順で行います。

      

[プログラム例]

  private void FreeArea(long P)
  {
     if(P<0) return;
     DataArea[P].Next=ErasedP;
     ErasedP = P;
  }

すでに,未使用要素であるような領域を返却すると,
未使用のリストが網状になってしまい,
未使用・使用の関係がメチャメチャになり
悲惨なことになることが多くあります。

したがってデバッグ時には,
以下のように返却されようとする要素が,
未使用領域でないかどうかを判定する処理を追加して
テストを行うことが多いようです。

[デバッグ時のプログラム例]

  private void FreeArea(long P)
  {
     if(P<0) return;
     // ***以下,チェック用***
      long PP = ErasedP;
     while(PP>=0)
     {
       if(PP==P)
       {
           MessageBox.Show("領域"+P.ToString() +"はフリーエリアです");
           return;
       }
       PP=next(PP);
      }
      // ****チェックここまで***
      DataArea[P].Next=ErasedP;
      ErasedP = P;
  }


番号 以下をクリックすると,該当箇所にジャンプします
(1) 考え方
(2) 初期化
(3) 領域の確保
(4) 領域の返却

1. 基本的なアルゴリズム

2. 基本的なデータ構造

3. 操作を伴うデータ構造

4. 探索

5. 再帰的アルゴリズム

6. ソート

7. 集合

8. 文字列処理

9. 色々なアルゴリズム


上のタイトルをクリックします