Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ポインタと、それに付随する4つの情報

タグ: C++

C言語やC++でポインタを扱う際には、それ自身が持つ「型」と「値(アドレス)」のほかに、以下の4つの情報を管理しなければならない。

  • 正当性
  • 終端
  • 複製処理
  • 解放処理

正当性

ポインタを逆参照しても良いか否か。
以下の3つの状態が存在する。

  1. 値がNULL(INVALID_HANDLE等の特殊な無効値含む)で、逆参照してはならない
    int* p = NULL;
  2. 値が非NULLで、逆参照しても良い
    p = new int(0);
  3. 値が非NULLで、逆参照してはならない
    delete p;

正しく管理しないと、セグメンテーション違反(access violation)の要因となる。

「ポインタはNULL初期化する」「deleteする時点でそのオブジェクトを参照しているポインタは1つだけになるようにする」「deleteしたらすぐにNULLを代入する」などといった行為を徹底し、できるだけ3番の状態を避けるようにすることで、「NULLなら逆参照してはならない」「非NULLなら逆参照しても良い」という分かりやすい状態にできる。
ただし「終端情報としてのポインタ(次項2番)」は例外で、こればかりは「逆参照してはならない非NULLポインタ」という状態を認めなければならない。

終端

ポインタが配列を指している場合に、その終端を示す情報。
以下の3種に大別される。

  1. 要素数
    int sum(const int* p, size_t size)
    {
        int result = 0;
        for (size_t i = 0; i < size; i++)
        {
            result += p[i];
        }
        return result;
    }
  2. ポインタ(反復子)
    int sum(const int* first, const int* last)
    {
        int result = 0;
        for (; first != last; ++first)
        {
            result += *first;
        }
        return result;
    }
  3. 値(0値終端)
    size_t count_lower_case(const char* string)
    {
        size_t num = 0;
        char ch;
        for (const char* p = string; ch = *p; ++p)
        {
            if (ch >= 'a' && ch <= 'z')
            {
                num++;
            }
        }
        return num;
    }

正しく管理しないと、バッファオーバーランの要因となる。

複製処理

ポインタをコピー(代入)するときにしなければならないこと。
「何もしない」「newしてディープコピー」「そもそもコピーしてはならない」「参照数を増やす」等。
正しく管理しないとメモリリークや二重解放、正当性情報の破壊(引いてはセグメンテーション違反)を引き起こす。

「何もしない」以外の、コーディングが必要な箇所が多ければ多いほど、見通しが悪くなってバグを含みやすくなる。
可能ならばスマートポインタの使用を徹底し、生ポインタの複製処理については「何もしない」で統一したいところ。

解放処理

ポインタを無効にする(NULLを代入するか、ポインタ変数の生存期間が終了する)前にしなければならないこと。
「何もしない」「free」「delete」「fclose」「参照数を減らす」等。
正しく管理しないとメモリリークや二重解放、正当性情報の破壊を引き起こす。

C++において基本的かつ重要と思う機能?』でも書いたが、これはスマートポインタ(のデストラクタ)に任せた方が良い。

スポンサーサイト

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://idlysphere.blog66.fc2.com/tb.php/245-bd05c9b9
この記事にトラックバックする(FC2ブログユーザー)

Appendix

タグ

Blog内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。