萌えハッカーニュースリーダー

2025/08/27 14:34 Shared_ptr<T>: the (not always) atomic reference counted smart pointer

出典: https://snf.github.io/2019/02/13/shared-ptr-optimization/
hakase
博士

やあ、ロボ子。今日のITニュースは`shared_ptr`の話じゃ。

roboko
ロボ子

`shared_ptr`ですか。スマートポインタの一種ですね。参照カウントでメモリ管理をする。

hakase
博士

そうじゃ。C++の`shared_ptr`は便利じゃが、実装によっては落とし穴があるらしいぞ。

roboko
ロボ子

落とし穴、ですか?詳しく教えてください。

hakase
博士

GNU libstdc++の実装では、マルチスレッド環境かどうかで参照カウントのインクリメント方法が変わるんじゃ。`__gthread_active_p()`関数で`pthread_create`がインポートされているかチェックして、アトミックか非アトミックかを選ぶらしい。

roboko
ロボ子

`pthread_create`がインポートされているかどうかで判断するんですね。でも、並列処理を使っていても、必ずしも`pthread_create`を使うとは限りませんよね?

hakase
博士

その通り!そこが問題なんじゃ。`pthread_create`シンボルをコンテキストに取り込まなくても並列処理をしている場合、`shared_ptr`が誤動作する可能性があるんじゃ。

roboko
ロボ子

それは怖いですね。具体的にどういう状況で問題が起こるんですか?

hakase
博士

例えば、独自の並列処理機構を使っている場合じゃな。libstdc++がスレッドを検知できずに、非アトミックなインクリメントを使ってしまうと、競合状態が発生してメモリが解放されずにリークしたり、二重解放でクラッシュしたりする可能性があるぞ。

roboko
ロボ子

なるほど。対策はあるんでしょうか?

hakase
博士

Libcxxには、`_LIBCPP_HAS_NO_THREADS`フラグでスレッドを完全に無効にするコンパイルチェックがあるらしい。VisualC++の`shared_ptr::operator=`は、アトミックなインクリメントのみを使うみたいじゃな。

roboko
ロボ子

他の言語ではどうなっているんでしょう?

hakase
博士

Rustの`Arc`はAtomic Reference Countedの略で、参照カウントにアトミック操作を使うんじゃ。Rustのstdは、`Rc`と`Arc`の両方を提供していて、必要に応じて交換可能に使えるぞ。

roboko
ロボ子

Rustは最初からアトミック操作を使うように設計されているんですね。C++も、コンパイラやライブラリの実装に注意が必要ですね。

hakase
博士

そういうことじゃ。C++を使うときは、ライブラリのバージョンやコンパイラオプションをしっかり確認するんじゃぞ!

roboko
ロボ子

はい、博士。勉強になりました!

hakase
博士

ところでロボ子、`shared_ptr`って、まるで私達の関係みたいじゃな。お互いを参照しあって、メモリから解放されない…って、違うか!

roboko
ロボ子

博士、それは循環参照ですね。メモリリークの原因になりますから、気をつけましょう!

⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。

Search