Effective C++ 第3章17項
次のような引数を持つ関数があるとする。
void Func( std::tr1::shared_ptr<Test> p, int value );
この関数を次のように呼び出したとする。
int getValue(); Func( std::tr1::shared_ptr<Test>(new Test), getValue() );
一見正しそうに見えるが問題がある。
C++では引数の評価順番は決まっていないので、上の例だと「new Test」が行われた後に「getValue()」が実行される可能性がある。このときもしgetValue()の処理で例外が発生して処理が中断されると、new Testで作成されたオブジェクトはスマートポインタに渡されなくなり、メモリリークとなってしまう。
解決方法はスマートポインタを使うときに独立したステートメントで行うこと。
std::tr1::shared_ptr<Test> p(new Test);
Func( p, getValue() );
私はなんとなく1行で処理を短く書いたコードのほうがかっこ良く見えてしまう。でもこういった落とし穴があるのでちゃんと理解してコードを書くことを心掛けないと。