【问题标题】:Do MSXML methods take memory ownership of their BSTR parameters?MSXML 方法是否获取其 BSTR 参数的内存所有权?
【发布时间】:2013-01-05 13:07:12
【问题描述】:

MSXML methods 是否取得其 BSTR 参数的内存所有权?

例如:loadgetElementsByTagNameselectSingleNode

我之所以问这个问题是因为我看到代码只是调用 CStringAllocSysString() 并将其传递给 MSXML 方法而不随后调用 SysFreeString()

编辑:
快速修复我使用_bstr_t 看到的代码:https://stackoverflow.com/a/14471409/109747(我的帖子)

【问题讨论】:

  • 不,他们为什么要这样做?你提供了一个字符串,你仍然是它的所有者。该方法将在必要时进行复制。
  • @RomanR。因为我是新手,我看到了一个代码,它只调用了 CString 的 AllocSysString() 而没有调用 SysFreeString()
  • @afriza:这会导致泄漏——这是 C++ 中一个非常常见的错误。
  • @afriza:这是“代码”,而不是“代码”...

标签: c++ memory-management com msxml bstr


【解决方案1】:

请注意,关于所有权的规则与特定库无关(假设是一个尊重规则的合理编写的库!)。

大多数情况下,它们都是关于常识的。

  1. 如果您从方法接收一个参数,那么您现在就是它的所有者。
    常识:其方法将值传回的对象无法知道如何使用参数值以及何时不再需要它。它别无选择,只能放弃所有权,而您是新的所有者。
  2. 如果您将参数“按值”传递给方法,您仍然是所有者。
    常识:方法不知道参数来自。它无法知道您是否还需要它。因此,它不可能是所有者。你是。
  3. 如果您参数“通过引用”传递给方法:

    • 您仍然是引用的所有者参见 2.)。
    • 您放弃了对传入值的所有权。
    • 您获得了所取回的价值的所有权。

    常识:该方法可以改变参考指向的东西。由于您无法提前知道这是否会发生,因此您无法控制发送给该方法的值的生命周期,因此您必须放弃对该方法的所有权。如果方法必须替换引用指向的值,那么它必须是释放它的方法。
    此外,无论该方法将参考点设置在其他位置还是保持原始值不变,该方法都无法控制您将使用该值做什么(参见 1.),因此它必须放弃它的通话结束时的所有权。
    如果该方法不修改引用指向的内容,那么它基本上会获得参数值的所有权,并在返回时将相同的所有权放弃给相同的值。

我知道;这可能都闻起来很臭……你知道你通常不拥有方法返回的底层对象。例如,从语义上可以理解,您从给定方法获得的对象与对同一方法的相同调用返回的对象相同(例如,某些->GetCurrentSession() 方法),那么您怎么能成为它的所有者呢?但我并没有说你拥有对象——我说你拥有参数值,在这种情况下,参数值是一个 COM 接口指针。在这种情况下,所有权意味着您必须在完成后对其调用->Release(),这不会影响指向同一底层对象的其他接口指针。

更新以添加一些信息
某些类型的事情可能会让人感到困惑,但你只需要剥离这些层就知道该怎么做:

  • BSTR 是指向内存的指针。是的,您通过引用传递内存,但在 COM 中您管理的是指针,而不是底层内存;因此“按值”/“按引用”讨论适用于 BSTR(指针)本身。也就是说,BSTR 参数是“按值”,BSTR* 是“按引用”。
  • VARIANT 有时包含值,有时包含引用。但同样,在 COM 中,您不直接管理底层值;您管理 VARIANT。 “按值”适用于 VARIANT,当 VARIANT 的所有者调用 VariantClear(...) 时,会处理任何基础引用。

@afriza:你提到的代码泄露了这些字符串。

【讨论】:

  • If you receive a parameter from a method => a return value 可能听起来更好? owned the parameter value 让我有点困惑,虽然我有点明白你的意思。
  • @afriza:我不想说“返回值”,因为这意味着 [out, retval]。它适用于所有 [out] 参数,[retval] 与否。但是让我想想如何改写它;我对我的措辞也不完全满意。
猜你喜欢
  • 1970-01-01
  • 2012-07-07
  • 2014-07-15
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
  • 2019-07-17
  • 1970-01-01
相关资源
最近更新 更多