2013-05-27 33 views
1

当我们创建从类型库例如对象堆

SomeClassPtr some_obj(__uuidof(SomeImplementation)); 

对象是some_obj在堆上创建或叠加么?我的意思是像

SomeClassPtr *some_obj = new SomeImplementation(); 

回答

1

在这种情况下,你的“指针”(SomeClassPtr)指向的内存块,这将是堆分配。

然而,这并不一定执行堆分配,因为它实际上是一个参考计数类型,其(通过IUnknown::AddRefIUnknown::Release)处理分配和解除分配。这意味着它可能会获取并递增先前分配的对象的引用计数,具体取决于存储在COM指针中的类型。

5

错误的思考方式。不是堆栈。

但这就是猜测结束的地方。这个COM对象可以存在于不同的进程中。或者在世界各地的一台机器上。你得到的只是一个界面指针,它指向你不知道的地方。可能是在堆上分配的实际对象。可能是与其他地方的存根交谈的代理。其他地方。这是一个功能,避免关心它。

+0

那么它有没有机会超出方法的范围? – MistyD

+0

您的*参考*可能超出范围而没有解除分配对象的实例*,反之亦然;根据对象的引用的生命周期和对象本身的生命周期来思考。 –

+0

这不是一个非常有意义的问题。东西停在方法的最后一个大括号处。如果你没有在接口指针上调用Release(),也没有将它存储在某个地方,以便稍后使用它,那么你会泄漏内存。某处。 –

0

其实,它比这个更有点儿。

严格地说,第一个例子是一个堆栈变量,而第二个例子是一个堆变量(假设新的处理不当被覆盖。

的怪异部分是因为,通过COM的本质,你不知道什么或在哪里或者如果(如果结果是一个AddRef,例如可能没有)发生任何其他分配;特别是对于需要跨越线程/进程边界的分配(这将始终是出错的情况),IMalloc :: Alloc(CoTaskMemAlloc())的默认实现是从COM对象实际创建/实例化的进程的堆中分配的。

As在其他地方指出,这是一个特点;你不需要关心。