January 29th, 2026
like1 reaction

How can I retain access to the data in a SAFEARRAY after my method returns?

The original problem our customer had was that the data in a SAFEARRAY disappeared even though they had called Safe­Array­Add­Ref. We learned why this is the case, but we still have to solve the customer’s problem: How can they extend the lifetime of a SAFEARRAY beyond the method that received it?

The SAFEARRAY is a unique-owner object. Once the owner calls Safe­Array­Destroy, the array is gone. You can extend the lifetime of the memory with Safe­Array­Add­Ref, but the data itself has vanished. The purpose of extending the lifetime of the memory is not to let you keep using the array, but rather to avoid accessing freed memory in case an array is destroyed out from under you.

If you don’t want the owner to call Safe­Array­Destroy, you have to convince the current owner to let you take ownership. Then you become the one responsible for calling Safe­Array­Destroy, and you can do that when you are finished with the array.

One way I thought of was to have the caller pass a VARIANT as an in/out parameter. On the way in, it contains a SAFEARRAY. You can then detach the parray from the variant and reset the variant’s type to VT_EMPTY. Detaching the parray lets you take ownership of the array, and setting the type to VT_EMPTY tells the caller that it no longer has an array.

Recall that the original intent was to allow the method to continue operating on the array after returning, while still avoiding the cost of having to create a separate copy of the array. Taking the parameter as an in/out variant makes it clear that the method might decide to change the array to something else, so if the caller still needs the data in the array, it had better pass a copy of the data, so that it can still use the original. So in that case, you didn’t really avoid the copy; you simply moved the copy into the caller. But in the case that the caller was going to destroy the array anyway, it could put the array in the variant, and if the method destroys the array as part of the method call, then no big deal. The array was getting destroyed anyway.

This isn’t a great solution, but at least it’s something.

Topics
Code

Author

Raymond has been involved in the evolution of Windows for more than 30 years. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie-jeebies. The Web site spawned a book, coincidentally also titled The Old New Thing (Addison Wesley 2007). He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information.

0 comments