警告 C28616
マルチスレッド化された AV 条件
この警告は、スレッドがプリエンプトされた場合、削除済みのオブジェクトにアクセスする可能性があることを示します。
解説
参照カウントがゼロになった後で、参照カウント済みのオブジェクトにアクセスすることはできません。
コード分析名: INTERLOCKEDDECREMENT_MISUSE1
例
この警告が発生するコード例を次に示します。 これは、この問題を招く可能性があるスレッド時間シーケンスの例です。 この例で、m_cRef
は this
のメンバーです。
スレッド T1 は if
条件を実行し、m_cRef
を 1 にデクリメントした後、プリエンプトされます。
別のスレッド T2 は if
条件を実行し、m_cRef
を 0 にデクリメントし、if
の本文 (ここで this
が削除される) を実行して、NULL
を返します。
T1 が再スケジュールされると、9 行目で m_cref
が参照されます。 このため、関連する this
ポインターが削除された後、およびオブジェクトのヒープが不明な状態になったときに、メンバー変数へのアクセスが発生します。
ULONG CObject::Release()
{
if (0 == InterlockedDecrement(&m_cRef))
{
delete this;
return NULL;
}
/* this.m_cRef isn't thread safe */
return m_cRef;
}
次のコードでは、オブジェクトが削除された後にヒープ メモリを参照していません。
ULONG CObject::Release()
{
ASSERT(0 != m_cRef);
ULONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
return NULL;
}
return cRef;
}