1

Do MSXML methods take memory ownership of their BSTR parameters?

For example: load, getElementsByTagName, or selectSingleNode

I'am asking this because I saw codes that simply call CString's AllocSysString() and pass it to MSXML methods without calling SysFreeString() subsequently.

EDIT:
Quick fix for the codes I saw using _bstr_t: https://stackoverflow.com/a/14471409/109747 (my post)

Community
  • 1
  • 1
Afriza N. Arief
  • 7,696
  • 5
  • 47
  • 74

1 Answers1

0

Note that the rules about ownership are not about the particular library (assuming a sensibly-written library that respects the rules!).

Mostly, they are all about common sense.

  1. If you receive a parameter from a method, you are now its owner.
    Common sense: The object whose method passed the value back has no way to know how the parameter value will be used and when it will not be needed anymore. It has no choice but relinquish ownership, and you are the new owner.
  2. If you pass a parameter "by value" to a method, you are still the owner.
    Common sense: The method doesn't know where the parameter came from. It has no way to know whether you still need it. Therefore, it cannot be the owner. You are.
  3. If you pass a parameter "by reference" to a method:

    • You are still the owner of the reference (see 2.).
    • You relinquish ownership of the value you passed in.
    • You acquire ownership of the value you get back.

    Common sense: The method can change what the reference points to. Since you can't know in advance whether this will happen or not, you cannot control the lifetime of the value sent to the method so you must relinquish ownership to the method. If the method must replace the value the reference points to, then it must be the one to release it.
    Also, whether the method makes the reference point at something else or leaves the original value untouched, the method can't control what you will do with that value (see 1.), so it must relinquish its ownership at the end of the call.
    If the method doesn't modify what the reference points to, then it basically acquires ownership to the parameter value, and relinquishes that same ownership to the same value when it returns.

I know; this might all smell foulish... you know that you usually don't own the underlying object returned by a method. For example, it might be semantically understood that the object you get from a given method is the same object returned by an identical call to the same method (e.g. some ->GetCurrentSession() method), so how could you be its owner? But I didn't say you owned the object - I said you owned the parameter value, and the parameter value in such a case is a COM Interface pointer. What ownership means in this case is that you must call ->Release() on it when you're done with it, which won't affect other Interface pointers to the same underlying object.

Updated to add some info:
Things can get confusing for certain types, but you just need to peel the layers to know what to do:

  • BSTR are pointers to memory. Yes, you pass the memory by reference, but in COM you manage the pointers, not the underlying memory; therefore the "by value"/"by reference" discussion applies to the BSTR (pointer) itself. That is, a BSTR parameter is "by value", a BSTR* is "by reference".
  • VARIANTs sometimes contain values, sometimes references. But again, in COM you don't manage the underlying values directly; you manage the VARIANTs. "By value" applies to the VARIANT and any underlying reference is dealt with when the owner of the VARIANT calls VariantClear(...).

@afriza: the code you mention is leaking those strings.

Euro Micelli
  • 33,285
  • 8
  • 51
  • 70
  • `If you receive a parameter from a method` => `a return value` may sounds better? And `owned the parameter value` is confusing me a bit, though I kind of getting what you mean. – Afriza N. Arief Jan 23 '13 at 01:35
  • @afriza: I didn't want to say "return values" because that implies [out, retval]. It applies to all [out] parameters, [retval] or not. But let me think about how I can rephrase it; I'm not totally happy with my wording either. – Euro Micelli Jan 23 '13 at 17:14