开发者

Why does this implementation of COM IUnknown::Release work?

开发者 https://www.devze.com 2023-02-07 19:08 出处:网络
From examples I\'v开发者_如何学Pythone seen COM IUnknown::Release() function implementation is something like that:

From examples I'v开发者_如何学Pythone seen COM IUnknown::Release() function implementation is something like that:

ULONG Release()
{
    InterlockedDecrement(&m_count);
    if(m_count == 0) {
       delete this;
    }
    return m_count;
}

So, if m_count is 0, so we're deleting "this" object, and returning the ref count. What I don't understand is why it works ?!?!

  1. Deleting the object wouldn't ruin the call stack or is it okay because it is being held by the thread, so it has nothing to do with the object ???

  2. If the object has been deleted, how is it possible that we can return m_count, it should've been deleted. I could have convinced myself that it's okay if after the delete the code would return hard-coded 0, but how come it can return the member ?!?!

Thanks a lot for your help! :-)


That code is bogus. One can never trust m_count after the decrement. The correct code is always like this:

ULONG Release()
{
     ULONG count = InterlockedDecrement(&m_count);
     if(count == 0){ delete this; }
     return count;
}


What you observe is undefined behavior. The call stack is not changed by delete this; and delete this by itself is always safe but renders this pointer invalid which means you can't dereference it anymore.

There're two possible explanations of what you observe. Either the implementation in question just doesn't dereference this pointer to obtain m_count when returning from the function - it has it loaded onto a register and just uses that value and so this is not dereferenced and you don't observe any problem or when delete finishes the memory occupied by the object is still mapped into the process address space and remains technically accessible and so dereferencing this succeeds and m_count is read successfully. I suppose the latter is more likely.

Whatever the explanation is that undefined behavior, you can't rely on that, use what user Remus Rusanu suggests in his answer.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号