std::make_shared にまつわるエトセトラ

C++11が世に出てもう5年経つので世の中のC++erさんにはもう常識なハナシかとは思いますがロートルおじさんは最近初めて知りました。結構ビックリ。

std::shared_ptr( new T(args…) );
std::make_shared( args… );

make_sharedはてっきり記述を楽するだけのものかと思ってたら、オブジェクトと管理用のメモリ領域を一体で確保してくれるとのこと。
一方上のようにフツーにnewしたものからshared_ptrを作成すると、オブジェクトのメモリと管理領域のメモリがそれぞれ別々に確保される。

C++プログラマーよ!std::make_sharedを安易に使うべからず! : 株式会社CFlatの明後日スタイルのブログ
make_shared で確保されたメモリ領域は,それを参照する weak_ptr が無くならない限り解放されない : 野良C++erの雑記帳

・管理領域を一体で確保するからメモリの割り当て回数が少なくて済む。その分速い
・make_sharedが管理領域をまとめて独自にメモリを確保するのでクラスのoperator new/deleteが呼ばれない
・make_sharedの中からオブジェクトを構築するのでpublicでないコンストラクタを呼び出す手段がない
・オブジェクトを指すshared_ptrが全てなくなりdesutructされた後にまだそのオブジェクトを指すweak_ptrが残っている場合、管理領域を残す必要があるためにそれと一緒に確保された(destructされた後の)オブジェクトのメモリ領域が残ってしまう。そのオブジェクトを指すweak_ptrも全部無くなれば解放される。

うーん、make_sharedを使うか使わないか、結構意識しないといけないですねコレ。。。