A customer had a method that received a SAFEARRAY, and they called SafeÂArrayÂAddÂRef to add a reference to it so that they could continue using the array after the method returned, but they found that if they tried to use the array later, the safearray->pData was NULL, and if they called SafeÂArrayÂAddÂRef again, it also gave them a null data pointer. They wanted to know if this was expected behavior. “Does COM invalidate a SAFEARRAY when a method returns, ignoring the reference count?”
Earlier, we looked at the difference between SafeÂArrayÂAccessÂData and SafeÂArrayÂAddÂRef, and that will be the key to untangling this riddle.
Scripting SAFEARRAYs are not reference-counted objects. When somebody says to destroy them, they are destroyed.
The SafeÂArrayÂAddÂRef function lets you extend the memory lifetime of the array descriptor and the array data, but the useful lifetime ends when the array is destroyed. The purpose of the SafeÂArrayÂAddÂRef function is to prevent you from operating on freed memory if somebody destroys the array out from under you.
In this case, what happens is that the caller provides a SAFEARRAY, and you call SafeÂArrayÂAddÂRef to extend its memory lifetime. When you return, the caller decides that it was a temporary array, so it calls SafeÂArrayÂDestroy. This renders the array contents useless, but since you added a reference (to the descriptor and the data), the memory for them is not freed, even though they don’t contain anything useful any more.
After the array has been destroyed, your calls to SafeÂArrayÂAddÂRef continue to extend the lifetime of the array descriptor and the data in it, but the descriptor had already been emptied out when the array was destroyed, so there is no data in the array any more. You are extending the lifetime of no data, which is why SafeÂArrayÂAddÂRef produces a null pointer as the data pointer.
To access the original memory, you need to do it through the pointer returned from the original call to SafeÂArrayÂAddÂRef.
But even that won’t help you, because the memory for the array data is zeroed out when the array is destroyed. You have a pointer to a bunch of zeroes.
Next time, we’ll look at ways of solving the customer’s problem, now that we understand why their approach didn’t work.
0 comments
Be the first to start the discussion.