次の方法で共有


警告 C28616

マルチスレッド化された AV 条件

この警告は、スレッドがプリエンプトされた場合、削除済みのオブジェクトにアクセスする可能性があることを示します。

解説

参照カウントがゼロになった後で、参照カウント済みのオブジェクトにアクセスすることはできません。

コード分析名: INTERLOCKEDDECREMENT_MISUSE1

この警告が発生するコード例を次に示します。 これは、この問題を招く可能性があるスレッド時間シーケンスの例です。 この例で、m_cRefthis のメンバーです。

スレッド 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;
}