过去,我们在软件中遇到过各种内存泄漏。我们发现这些发生主要是由于我们自己的“免费”-Methods 的错误使用,它释放了 Queue-Message-Data 等。
问题是,在我们最深入的工具函数中,有两种方法可以释放动态分配的内存,具有以下签名:
void free (void *pData);
void free (void **ppData);
两种方法基本上都做同样的事情,除了第二种方法首先取消引用数据。我知道只用这两者之一就可以做所有事情,但可以说该软件多年前就是这样设计的,现在到处都有代码使用这两者。
当有人像这样实现对这些方法的调用时,问题就来了:
QueueMessage *pMsg;
pMsg = myQueue.read(...); // dynamically allocates space for the msg and fills it
// Do something
myQueue.free(&pMsg); // << WRONG!
上面的代码应该将指向消息的指针传递给自由方法。基本上它会工作,但由于编译器不知道在这种情况下使用哪个函数,它使用free(void *pData)
然后尝试释放Pointer的方法,而不是Pointer 指向的内存。当然,解决方案很简单,要么:要么
myQueue.free(pMsg);
myQueue.free((void**)&pMsg);
两者都会起作用。既然我已经描述了问题和解决方案,我想知道:有什么方法可以确保使用这些方法的程序员以正确的方式使用它们?我已经阅读了VS2005 中的标头注释,它们非常有用,但似乎并没有满足我的需要。如果指针的引用被传递给第一个方法,如果有一种方法可以产生警告,那就太好了,这样程序员至少会得到他的代码有问题的提示。
顺便说一句,我正在使用 Microsoft VS2005,如果需要,可以升级到 VS2008。这是一个迁移到 VS2005 的 C++ 应用程序,因此与 .NET 兼容。