我正在努力修复来自第三方软件包的内存泄漏(Zinc Application Framework,一个GUI窗口框架,大约在1999年[!])。我正在使用Microsoft Visual Studio 2005 C ++在Windows 7机器上工作(请保持喘气)。我很好奇是否有人对可能出现的问题有任何见解。
以下是我收到的消息,表明存在内存泄漏:
Detected memory leaks!
Dumping objects ->
{291} normal block at 0x003DE228, 36 bytes long.
Data: <` > 60 B6 1D 10 00 00 00 00 00 00 00 00 00 00 CD CD
Object dump complete.
The program '[3496] TempZAF3.exe: Native' has exited with code 0 (0x0).
跟踪到存储器分配块291,我进入以下方法:
long ZafCache::Get(long type, long value)
{
// Find a matching cache element.
CacheElement *element;
for (element = (CacheElement *)First(); element; element = (CacheElement *)element->Next())
if (element->type == type && element->value == value)
{
// Move the element to the front of the list because it is
// most recently used.
if (element != first)
{
ZafList::Subtract(element);
ZafList::Add(element, first);
}
element->useCount++;
return element->handle;
}
// Create a cache element if one didn't already exist.
long handle = CreateFunction(type, value);
element = new CacheElement(type, value, handle);
ZafList::Add(element, first);
// Remove a cache element if the cache is full.
if (++count >= size)
{
element = (CacheElement *)last;
if (element->useCount <= 0)
{
ZafList::Subtract(element);
DestroyFunction(element->type, element->value, element->handle);
delete element;
element = ZAF_NULLP(CacheElement);
count--;
}
}
return handle;
}
调试器专门针对上述方法中的以下代码行:
element = new CacheElement(type, value, handle);
啊哈。此代码后面没有“delete element”命令,至少在此方法中是这样。显然,这是罪魁祸首 - 我们为CacheElement分配内存,而且我们永远不会释放内存。
大!因此,在将元素添加到静态ZafList之后,只需删除该元素,然后查看是否可以解决问题。不 - 我们得到一个未处理的异常,访问违规读取某个位置。好的,我们来试试吧。我们将注释掉代码行
//ZafList::Add(element, first);
并添加
delete element;
宾果。没有更多的内存泄漏。唯一的问题是我们实际上想要将元素添加到ZafList。
以下是ZafList :: Add方法的代码:
ZafElement *ZafList::Add(ZafElement *newElement, ZafElement *positionElement)
{
// Add the element to the list.
if (!first) // Put at the first of the list.
{
newElement->previous = newElement->next = ZAF_NULLP(ZafElement);
first = last = newElement;
}
else if (!positionElement) // Put at the end of the list.
{
newElement->previous = last;
newElement->next = ZAF_NULLP(ZafElement);
last->next = newElement;
last = newElement;
}
else // Put before the specified element.
{
newElement->previous = positionElement->previous;
newElement->next = positionElement;
if (!positionElement->previous)
first = newElement;
else
positionElement->previous->next = newElement;
positionElement->previous = newElement;
}
++count;
return (newElement);
}
以下是显示ZafList和ZafCache以及ZafElement和CacheElement之间关系的代码:
// Cache used for cacheing GDI pens and brushes.
class ZafCache : public ZafList
{
public:
ZafCache(int size,
long (*CreateFunction)(long type, long value),
void (*DestroyFunction)(long type, long value, long handle));
virtual ~ZafCache(void);
long Get(long type, long value);
int Release(long handle);
private:
int count;
int size;
long (*CreateFunction)(long type, long value);
void (*DestroyFunction)(long type, long value, long handle);
class CacheElement : public ZafElement
{
public:
long handle;
long type;
long value;
int useCount;
CacheElement(long type, long value, long handle);
};
};
ZafList析构函数是否应释放为CacheElement分配的内存?名义上,看起来ZafList析构函数应该完成这项工作,因为它调用了下面的方法。
void ZafList::Destroy(void)
{
ZafElement *tElement;
// Delete all the elements in the list.
for (ZafElement *element = first; element; )
{
tElement = element;
element = element->next;
delete tElement;
tElement = ZAF_NULLP(ZafElement);
}
first = last = current = ZAF_NULLP(ZafElement);
count = 0;
}
然而我们的内存泄漏了。所以问题归结为:在将其添加到ZafList后,如何释放为CacheElement分配的内存?在此先感谢您的任何建议!
答案 0 :(得分:2)
代码看起来都不错。
但仅仅因为内存泄漏软件说存在泄漏并不一定意味着存在泄漏。可能是在调用列表的析构函数之前挂起了内存泄漏检测代码(如果列表是文件范围静态存储持续时间对象,则会发生这种情况。)