警告 C28616

多线程 AV 条件

此警告指示线程在被抢占时有可能访问已删除的对象。

注解

引用计数为零后,不应有对引用计数对象的访问权限。

代码分析名称:INTERLOCKEDDECREMENT_MISUSE1

示例

下面的代码将生成此警告。 这是可能暴露此问题的线程时间序列示例。 在此示例中, m_cRef 是 的成员 this

线程 T1 执行条件 if ,递减 m_cRef 到 1,然后被抢占。

另一个线程 T2 执行 if 条件,递减 m_cRef 为 0,执行 if 正文 (this 删除) ,并返回 NULL

重新计划 T1 时,它将引用 m_cref 第 9 行。 因此,在删除相关 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;
}