Cでポインタを引数に渡すときに勘違いするなよ

下のようなのはバグに近いと思うんです。


void hoge (char *text) {
     if (text == NULL) return;
     free(text);
     text = NULL;
}

いや、別にちゃんと動くし、間違ってないし、そういう意味ではバグではないんですが。最後の「text = NULL」というのが意味がない。こう書いてしまう人は結構いるんじゃないかと思うんです。(自分も含めて)
上記では冒頭でNULLチェックをしているし、最後にNULLを代入するので連続で呼ばれても2重解放はしないぜ!って感があふれています。でも連続で呼ばれたら2重解放になります。なぜなら呼び出し元のtextはNULLにできないから。


void hoge (char *text) {
     if (text == NULL) return;
     free(text);
     text = NULL;
}

int main() {
   char *text = NULL;
   text = (char *)malloc(10);
   hoge(text);
   if (text != NULL) {
       printf("いやん\n");
   }
   return 0;
}

「いやん」となるわけです。hogeに渡されるのはtextのコピーなので、hogeの中で値を変えても無意味なわけだけども、textの指している先のデータをhogeの中で書き換えることはできるので勘違いしやすいんじゃないかなと。
あるいは下記のようなことはできません。


void fuga(char *text) {
   text = (char *)malloc(10);
}

いや、やってもいいけど期待したとおりには動きません。上のようなことをやりたい場合は


void fugaShinuchi(char **text) {
   (*text) = (char *)malloc(10);
}

int main() {
   char *text = NULL;
   fugaShinuchi(&text);
   free(text);
   return 0;
}

初心忘るべからずということで。

以上

コスミー について

昔(?)はゲーム作ってました。 今もなんか作ろうとしています。
カテゴリー: C言語 パーマリンク

Cでポインタを引数に渡すときに勘違いするなよ への5件のフィードバック

  1. 匿名 のコメント:

    塩です。
    お久しぶり。

    hogeに渡されるのは*textのコピーじゃないかな?

  2. コスミー のコメント:

    あ、お久しぶりです。
    あーこれ、失敗しましたね。hogeとmainの変数が両方textだったのでややこしいですね。
    mainから見たときのtextのコピーという意味だったんです。いや、それも違うのかな?text自体はポインタ変数なのでポインタ変数の値がコピーされたポインタ変数が渡されるという、そういう理解は共有できていると思うんですけど・・・。なんて書くのが正しいのかわかりません!

    P.S. mixiの方のぞいてみます。

  3. legiaquangcao.com のコメント:

    Having read this I thought it was rather informative.
    I appreciate you taking the time and effort to put this
    article together. I once again find myself personally
    spending a significant amount of time both reading and commenting.

    But so what, it was still worthwhile!

  4. Rebekah のコメント:

    Great post! We will be linking to this great article on our website.

    Keep up the great writing.

  5. Dong のコメント:

    Fantastic post however I was wanting to know if you could write a litte more on this subject?

    I’d be very thankful if you could elaborate a little bit more.
    Thank you!

コメントを残す

メールアドレスが公開されることはありません。