内存泄漏-释放和删除

Memory leak - release and delete

本文关键字:删除 释放 泄漏 内存      更新时间:2023-10-16
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;

我需要"delete size"在上面的代码中?如果我包含了"delete size",是否会因为没有使用New而导致内存泄漏?或者在对CoCreateInstance的调用中有一个New。

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

从c++的角度来看,你所做的是好的。在空指针上调用delete是无操作的。然而,这是不必要的。

从vc++ 6的角度来看,我不能说,它是出了名的不兼容。我无法想象为什么这可能是一个问题。但是,这当然是没有必要的。

在这个指针被设置为NULL之前,绝对不要对它调用delete。你没有分配new,所以不要调用delete。这里的资源管理由COM函数负责。

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

  1. 你并不总是知道那个服务器是不是用c++写的。在非c++对象上执行delete是未定义行为。
  2. 即使服务器是用c++编写的,你也不知道它被分配到哪个堆上,也不知道delete是否会正确释放内存或触发未定义的行为。
  3. 在没有虚析构函数的接口指针上调用delete,这是未定义的行为。
  4. 你并不总是知道你被服务的是一个真实的对象还是一个代理。在代理上执行delete是未定义的行为。
  5. 一旦你调用了Release(),对象可能已经自我删除了,再次执行delete是未定义的行为。一些第三方可能已经获得了对象的所有权——例如,一些全局指针实例可能已经被设置为你的对象。如果你设置了delete,其他指针就会悬空,这可能会导致以后的未定义行为。

底线:在这种情况下永远不要使用delete。调用Release()来释放对象的所有权,这就足够了。

如果我包含"delete size",是否会因为没有使用New而导致内存泄漏?

通过调用delete通常不会得到内存泄漏。您可以并且很多时候获得内存损坏。这两者是非常不同的:内存泄漏意味着你的程序保留了它实际上没有使用的内存,随着时间的推移,如果泄漏的内存继续增长,程序可能会崩溃;内存损坏意味着您以某种方式破坏了内存中的重要簿记结构,并且可能很快就会崩溃(至少您应该希望崩溃,否则情况会更糟)。内存损坏的一个非常常见的原因是使用错误的例程释放内存,特别是在Windows上(在UNIX上重新定义mallocfree是一种传统,因此UNIX系统通常会特意确保可以这样做)。

或者在CoCreateInstance

的调用中是否有New

CoCreateInstance内部的内容应该由Release()处理。至少,您不应该仅仅因为有一个指针就释放内存。您需要知道内存是如何分配的,以便正确地释放它。

我假设size->Release()正在释放操作系统资源(文件句柄等)。因此,在将size设置为null之前,请将delete size紧接在后面。