topazの遊び場

いろいろやってみる

そろそろC++やるぞパート15 ポインター ~ スマートポインタ ~

そろそろC++やります

そろそろC++をやります。そろそろC++をやりたいからです。
何回やるかはわかりません。基礎を理解するまではやろうと思います。

という感じでやっています。

※ 初心者がメモレベルで記録するので、技術記事としてはお力になれないかもしれません。

内容

  • 今回は、スマートポインタをわかりやすい記事を参考にして概要を掴みます。

スマートポインタとは

簡単にいうと、生ポインタより使いやすくなったポインタです。


生ポインタの問題点

1. newで生成した後に、deleteしないとメモリリークが生じる。

int main()
{
    int *intPtr = new int();
    *intPtr = 1234;
    cout << *intPtr << endl;
    // deleteしていない
    return 0;
}

2. 念の為と、何度もdeleteするとエラーが生じる。

int main()
{
    int *intPtr = new int();
    *intPtr = 1234;
    cout << *intPtr << endl;
    delete intPtr;
    delete intPtr;  // 2回目のdeleteは実行時エラーとなる
    return 0;
}

この生ポインタのバグの元になりやすいメモリの確保/解放周りを楽にすることができるのが、スマートポインタです。

コード上では、このようになります。

int main()
{
    shared_ptr<int> x = make_shared<int>();
    *x = 1234;
    cout << *x << std::endl;
    return 0;
}

スマートポインタのアドレスの確認

unique_ptr<>を使用してアドレスの確認を行います。通常のポインタとスマートポインタの変数自体のアドレスと中身を見てみます。

int *intPtr = new int(7654);
unique_ptr<int> l(intPtr);

cout << &intPtr << endl;
cout << intPtr << endl;
cout << &l << endl;
cout << l << endl;

Output:

0x16d21ada8
0x142f04090
0x16d21ada0
0x142f04090

スタック領域に intポインタ intPtrと uniqueポインタlのメモリが割り振られ、両ポインタが同じアドレス(0x142f04090)のヒープ領域を参照しています。

所有権

スマートポインタはリソース(メモリなど)への所有権という考え方で出来ています。

  • スマートポインタは初期化後の生ポインタを所有
  • スマートポインタを介してメモリにアクセス
  • 生ポインタから解放されることはない

スマートポインタを定義した後に、元の生ポインタを削除しようとすると実行時エラーが生じます。

int *intPtr = new int(7654);
unique_ptr<int> l(intPtr);
delete intPtr;

C++ 標準ライブラリのスマートポインタ

  • unique_ptr
  • shared_ptr
  • weak_ptr

参考記事

感想

スマートポインタ楽しみにして心構えていましたが、実際はそこまで難しくもなさそうで、とても便利!という感じでした。

スマートポインタの種類によって所有権の取り扱いが変わるようなので、次回からは一つずつ見ていきます。