内存泄漏 - 释放和删除

时间:2011-08-25 19:56:24

标签: c++ memory-leaks com vc6 delete-operator

IFSUPCUTILSize* size = NULL;
CoCreateInstance(CLSID_UTILSize, NULL, CLSCTX_INPROC_SERVER, IID_IFSUPCUTILSize,    reinterpret_cast<void**>(&size));

if (size != NULL){
size->Release();
size = NULL;
}
delete size;

上面的代码中是否需要“删除大小”? 如果我包含“删除大小”,我会有内存泄漏,因为我没有使用新的。 或者在CoCreateInsatnce的调用中是否有新的内容。 我使用VC ++ 6构建它。

5 个答案:

答案 0 :(得分:10)

COM接口被引用计数。 CoCreateInstance()返回一个指向COM对象的接口指针,该对象的引用计数已经递增。调用Release()会减少引用计数。当引用计数降为零时,COM对象自动释放自身。不要在COM接口指针上调用delete!始终只使用Release()

答案 1 :(得分:4)

从C ++的角度来看,你正在做的事情很好。在空指针上调用delete是一个无操作。但是,这是不必要的。

从VC ++ 6的角度来看,我不能说,这是出了名的不合规。我无法想象它为什么会成为一个问题。但同样,这当然是不必要的。

在将此指针设置为NULL之前,绝对不要调用此删除。您没有使用new分配,所以不要调用delete。此处的资源管理由COM功能负责。

答案 2 :(得分:1)

永远不要尝试使用delete来释放由其他模块实现的COM服务器(这是您的情况)。

  1. 您并不总是知道该服务器是否是用C ++编写的。对非C ++对象执行delete是未定义的行为。
  2. 即使服务器是用C ++编写的,也不知道它在哪个堆上分配,以及delete是否会正确释放内存或触发未定义的行为。
  3. 您在声明为没有虚拟析构函数的接口指针上调用delete - 这是未定义的行为。
  4. 你不会总是知道你是否被送达了真实物品或代理人。在代理上执行delete是未定义的行为。
  5. 调用Release()后,对象可能已自行删除,再次执行delete是未定义的行为。
  6. 某些第三方可能拥有该对象的所有权 - 例如,某些全局指针实例可能已设置为您的对象。如果你delete那些其他指针将变为悬空,并且可能会在以后导致未定义的行为。
  7. 底线:在这种情况下不要使用delete。调用Release()以释放对象的所有权,这就足够了。

答案 3 :(得分:0)

  

如果我包含“删除大小”,我是否会因为没有使用New而发生内存泄漏。

调用delete通常不会导致内存泄漏。你可以多次 会导致内存损坏。这两者是非常不同的:内存泄漏意味着你的程序保留在它实际上没有使用的内存中,随着时间的推移,如果泄漏的内存继续增长,程序可能会崩溃;记忆腐败意味着你以某种方式破坏了记忆中重要的簿记结构,很可能会很快崩溃(至少你应该希望崩溃,替代方案更糟)。 One very common cause of memory corruption is deallocating memory with the wrong routine,特别是在Windows上(在UNIX上重新定义mallocfree是一种传统,因此UNIX系统often go out of their way to make sure it's possible to do that)。

  

或者对CoCreateInstance

的调用是否有新的内容

CoCreateInstance内的任何内容都应由Release()处理。至少,你应该永远不要因为你有一个指针而释放内存。您需要知道如何分配内存以便正确释放它。

答案 4 :(得分:-1)

我假设size-&gt; Release()正在释放OS资源(文件句柄等)。因此,在将size设置为null之前,请立即删除大小。