SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Modern C++入門

生のポインタは使わないで! Modern C++のメモリ管理

第3回 ポインタはスマートポインタで!

  • このエントリーをはてなブックマークに追加

 本連載では、Modern C++と称されるC++について、Modern C++らしい言語仕様をピックアップし紹介していきます。第3回は、スマートポインタについて紹介します。高度なメモリ管理には生のポインタの使いこなしが必須という古い常識はもはや通用しません。メモリを効率よく、しかも安全に使うことを実現しているスマートポインタについて理解を深めます。

  • このエントリーをはてなブックマークに追加

はじめに

 C言語から派生したオブジェクト指向プログラミング言語であるC++は、21世紀に入ってまったく別物とも言えるプログラミング言語に成長していきました。それは、Modern C++と称されています。1990年代にC++を触っていたプログラマが現在の仕様を知れば、隔世感に苛まれるのではないでしょうか。本連載では、かつてはC++をたしなんでいたという方、今からC++言語を始めるという方に向けて、Modern C++らしい言語仕様をピックアップし紹介していくことで、今のC++言語の姿を理解していただきます。

対象読者

  • かつてはC++をたしなんでいたという方
  • 今からC++言語を始めるという方
  • モダンなプログラミング言語のパラダイムに興味のある方

必要な環境

 本記事のサンプルコードは、以下の環境で動作を確認しています。

  • macOS Ventura/Windows 10(64bit)
    • Xcode Command Line Tools 2395
    • MinGW GCC 9.2.0

スマートポインタって何?

 20世紀のC++プログラマ(筆者)が、今(21世紀)のC++を知って驚く連載の第3回です。今回は、スマートポインタです。第1回では「生のポインタは使わないで!」と、C言語やC++言語を使いこなす上での関門的な機能を頭から否定するようなことを書いてしまいましたが、「それなら仕方ないな」「スマートポインタすごいじゃないか」と納得感のあるようにスマートポインタを紹介するのが今回の目的です。

[NOTE]C++プログラムのコンパイル

 以降のサンプルは、基本的に「gcc -o 出力先ファイル名 ソースファイル名」でコンパイルできますが、環境によってはライブラリやC++バージョンの指定が必要になることがあります。コンパイルやリンクでエラーが発生するときには、以下のようにライブラリの指定(-lstdc++)、C++バージョンの指定(-std=c++11)の追加を検討してください。

% gcc -o sample sample.cpp -lstdc++ -std=c++11	// c++14, c++17, c++20など

ポインタのおさらい

 まずは、C言語のポインタからおさらいしましょう。今でも初学者(40年前の筆者です)を悩ませているポインタですが、機能としてはメモリ上のどこかを指し示すということ以外にはありません。つまりアドレスです。これのどこが悩ましいのか? それは、大きく以下の2点に集約されると筆者は勝手に思っています。

  • 意図する場所をきちんと指すようにするのが難しい
  • 動的なメモリ領域の管理が難しいというか面倒

 本記事を読むような経験豊かで賢明な読者なら、何を言わんとしているか自明ですね。ポインタはあくまでもアドレスなので、そのアドレスが指す先が常に有効かつ意図した場所であることをプログラマが管理しなければなりません。ポインタは演算や代入が可能なので、なんか「++」とか「-=」とかやったり別のポインタにコピーしていたりしていたら、ワケのわからないことになってしまった、ということにもなりがちです(経験談)。

 あと、大きな配列を使いたいとか、そういう場合にはmalloc/freeのペアを使いますが(筆者はcalloc派)、これが結構曲者で、確保と解放をきちんと対で書くことができるとなると、かなりの熟練者ですね。しかもmallocには確保できない場合の判定もあり、しかもfreeは無効なポインタでも受け入れてしまうとか、仕様上どうなの?といった振る舞いもあります。

 どっちも、キチンとやれば問題ないさ!というのが正論でしょうが、じゃぁアンタは何でもキチンとできるの?と聞かれればグウとなってしまうことでしょう。プログラミングも人間のやること、できれば失敗のないように言語機能やライブラリでフォローしたいものです。

 そこで、スマートポインタです。「スマート」という名の通り、「賢い」ポインタです。正しい場所を指さないポインタ(ダングリングポインタとか)、freeを漏らしちゃったとかいうメモリリークといった、ポインタとメモリに関わる好ましくないことを、できるだけ排除してくれます。

スマートポインタの3つの種類

 スマートポインタには、3つの種類があります。どのように違うかというと、「所有権」という仕組みへの関わり方によって使い分けます。所有権とは、簡単にいうとメモリ領域の所有者を明確にして、そのメモリ領域の利用の権利を得る代わりに解放の義務を負うという仕組みです。この所有権の仕組みによって、メモリ領域を安全に使えるというわけです。ここでは、所有権との関わりで3つの種類があるのだな、ということをだけ知っておいておいてください。

  • std::unique_ptr:一つのスマートポインタだけが所有権を持つ
  • std::shared_ptr:複数のスマートポインタで所有権を共有できる
  • std::weak_ptr:shared_ptrの管理するメモリ領域への参照を持つ

 今回は、所有権と一対一で対応するスマートポインタであるstd::unique_ptr(以降、名前空間は省略)を中心に、C++のバージョンによるサポート状況を示すためにstd::shared_ptrも補足的に紹介していきます。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
スマートポインタを初期化する

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
Modern C++入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 山内 直(WINGSプロジェクト ヤマウチ ナオ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook <個人紹介> WINGSプロジェクト所属のテクニカルライター。出版社を経てフリーランスとして独立。ライター、エディター、デベロッパー、講師業に従事。屋号は「たまデジ。」。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/18446 2023/10/20 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング