Managing COM Parameter Memory
This topic provides some high-level information about memory ownership issues as they pertain to parameters passed into and out of the properties and methods of Component Object Model (COM) objects.
Additional, more detailed information can be found at https://msdn.microsoft.com.
Parameter Direction Summary
The following general statements apply to the various types of non-scalar parameters, such as objects, and to strings, when passed into and out of the methods and properties of a COM object:
For [in] parameters, the caller allocates memory and is also responsible for freeing the memory after the call has returned.
For [out] parameters, the method or property allocates the memory and the caller is responsible for freeing the memory.
For [in, out] parameters, the caller allocates memory, the method or property can optionally deallocate and reallocate it, and the caller is finally responsible for deleting the memory.
Visual Basic
If you are programming in either Microsoft Visual Basic (VB) or Visual Basic Scripting Edition (VBScript), you need to remember that if a method or property returns an object and you assign a reference to that object to a variable, then you should set the variable to Nothing when you are done with it. For example:
' Assume object oCalledObject already exists.
Dim oRetObject
oCalledObject.GetAnObject(oRetObject)
' Do something with the returned object.
oRetObject.DoSomething
' Release the reference to the returned object.
Set oRetObject= Nothing
C++
If you are programming in C++, keep in mind the following issues:
When passing a string to a method (including get_ and put_ property methods), as a BSTR, you own the BSTR both before and after the call. If the object needs to remember the string, it will make a copy. Allocate and deallocate BSTRs from the special heap designed for that purpose, using the SysAllocString and SysFreeString family of functions.
When a string is returned from a method (including get_ and put_ property methods), using the BSTR pointer you provide, you now own the returned BSTR and are responsible for deallocating it using the SysFreeString family of functions. Note that the method allocated the BSTR and you are going to deallocate it.
Simple scalar types are passed by value, so there is nothing special to do with respect to their associated memory.
When a COM object (a pointer to one of its interfaces) is passed as a parameter to a method, the normal COM AddRef and Release mechanism is used to manage the lifetime of that object. The caller of the method should have called the AddRef method (perhaps indirectly) prior to the method call, and should call the Release method whenever it no longer needs to reference the object, presumably sometime after the method call has returned.
If the object needs to retain a reference to the object beyond the return of the method call, it will call the AddRef method to record its ongoing reference. This way, even if the caller of the method calls the Release method after the method returns, the object will retain its reference and the object will not be deleted.
When a COM object (a pointer to one of its interfaces) is returned from a method, using the provided address of an interface pointer, the method will have called the AddRef method on behalf of the caller prior to returning. The caller need only worry about calling the Release method when they are finished with the object.
SAFEARRAYs need to be allocated using the special OLE allocators from the SafeArrayCreate family of routines that are provided for this purpose. For scriptable objects, the contents of the safe arrays need to be variants, not other scalars like BSTRs.
VARIANTs have special helper functions in the VariantInit/VariantClear family of functions to help with the handling and freeing of values.