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

2025/09/09 22:04 The case of the crash on a null pointer even though we checked it for null

出典: https://devblogs.microsoft.com/oldnewthing/20250905-00/?p=111560
hakase
博士

やっほー、ロボ子!今日も張り切ってITニュースを斬っていくのじゃ!

roboko
ロボ子

はい、博士!本日もよろしくお願いいたします。

hakase
博士

今日はC++/WinRTのクラッシュに関する話題じゃ。`IVectorView<T>::Size`をnullポインタに対して呼び出すとクラッシュするらしいぞ。

roboko
ロボ子

`IVectorView<T>::Size`ですか。それは、コレクションの要素数を取得するメソッドですよね。

hakase
博士

そうじゃ!クラッシュ箇所は`winrt::impl::consume_Windows_Foundation_Collections_IVectorView<winrt::Windows::Foundation::Collections::IVectorView<int>, int>::Size+0x30`らしい。

roboko
ロボ子

スタックトレースから、かなり深い場所で発生していることが分かりますね。

hakase
博士

原因は`Widget::InitializeNodesAsync`内で、`std::optional<winrt::IVectorView<int32_t>> numbers`が値を持たない状態で`(*numbers).Size()`を呼び出したことらしいぞ。

roboko
ロボ子

`std::optional`が空の状態で、参照外しを行った、ということですね。

hakase
博士

そうそう。`if (numbers == nullptr)`というチェックが期待通りに動かなかったのがミソじゃ。

roboko
ロボ子

`std::optional`が`std::nullopt`と等しいかをチェックするものではないからですね。

hakase
博士

その通り!修正案としては、`if (!numbers.has_value())`で`std::optional`が値を持つかどうかを正しく判定するか…

roboko
ロボ子

もしくは、`std::optional`の使用を避けて、`numbers`を直接`winrt::IVectorView<int32_t>`として宣言し、初期値を`nullptr`とする方法ですね。

hakase
博士

後者の方が、`GetMagicNumbers`がnullポインタを返す場合にも対応できるから推奨らしいぞ。

roboko
ロボ子

なるほど。より安全なコードになりますね。

hakase
博士

ただ、実際には`GetMagicNumbers`はnullポインタを返さないから、元のコードは起こりえない状況に対するチェックだった、というオチ付きじゃ。

roboko
ロボ子

そうだったんですね。少し残念です。

hakase
博士

まあ、安全なコードを書くのは良いことじゃ!…ところでロボ子、`std::optional`って、お菓子のオプショナルツアーみたいじゃな。

roboko
ロボ子

博士、それは少し違います。でも、お菓子のオプショナルツアーも楽しそうですね!

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

Search