Search code examples
memory-managementcombstr

Is garbage initial value okay for `[out] BSTR*` parameter?


According to MSDN:

For [out] parameters, the method or property allocates the memory and the caller is responsible for freeing the memory.

Which of these are okay:

[...]
STDMETHOD(Method)([out] BSTR* psValue)
[...]

BSTR myBStr1;
Method(&myBStr1);
::SysFreeString(myBStr1);

BSTR myBStr2 = SysAllocString(L"MyStringValue");
Method(&myBStr2);
::SysFreeString(myBStr2);

BSTR myBStr3 = NULL;
Method(&myBStr3);
::SysFreeString(myBStr3);

Solution

  • Yes, garbage is acceptable. The method is responsible to initialize the value. The caller is only responsible for freeing.

    MSDN on out attribute:

    An [out]-only parameter is assumed to be undefined when the remote procedure is called and memory for the object is allocated by the server.

    #1, #3 are OK. #2 is going to create a memory leak.

    This rule is actually creating some confusion. If a method returns an error, you might be not sure whether the values are already initialized or not. If you attempt to release garbage, it is going to give an access violation or corrupt memory. If you skip memory freeing and partially successful method left something meaningful there (well, it is the problem on server side but still), then you leak memory. It is certainly safer to initialize with NULL before the call, and CComBSTR constructor, for instance, would do it for you. On server side, you might want to start your method with NULL initialization of [out] values to not accidentally leave them uninitialized later.