# 开辟内存要跟释放内存成对出现。
# 开辟数组,释放数组。
# debug状态下,如果提示多少字节泄露,可以检查跟那个宏的大小一致,再定位开内存的位置。
#有如下错误:
Detected memory leaks! Dumping objects -> {1654} normal block at 0x01CC1B28, 40 bytes long. Data: 54 00 69 00 63 00 6B 00 65 00 74 00 20 00 69 00 {1650} normal block at 0x01CC1BF0, 16 bytes long. Data: 64 6B E8 95 68 79 0D 4E FD 80 7F 4F 28 75 00 00 Object dump complete.
我们来看一下输出信息的格式。
{xxx} — 表示程序运行后第xxx次内存分配发生了泄漏,即内存分配编号;
xxx block — 表示内存块类型,包括三种:普通(normal)、客户端(client)和运行时(CRT);
at 0xFFFFFFFF — 表示发生泄漏的内存地址,用十六进制表示;
xx bytes long — 表示发生泄漏的内存大小;
Data:xxx — 表示内存数据信息,一般输出前16字节的内容。
内存泄漏的地址、大小和数据信息很难对我们的定位起到有效地帮助,但是如果我们能够让程序停在分配有泄漏的内存的地方,然后根据调用堆栈(Call Stack)里的信息,就可以很方便的定位是哪个语句出现问题。幸运的是,VC的C运行库(C run-time library)为我们提供了一个这样的函数:CrtSetBreakAlloc,声明如下:
long _CrtSetBreakAlloc( long lBreakAlloc );
其中参数lBreakAlloc即为内存分配号(花括号中的数字)。我们只要在程序初始化函数中添加语句:_CrtSetBreakAlloc(858)就可以使程序在Debug F5运行时自动断点到我们想要的位置。
使用这个函数进行内存泄漏定位有个条件,即发生内存泄漏的分配号是固定的,每次启动程序不会随机变化。
但是如果我们的程序比较大,内存泄漏也不止一个,用上面的方法调试可能会很麻烦,需要经常更新代码并重新编译程序。还有更好的方法。
解决方法
1、在程序开始的地方,加上代码:_CrtSetBreakAlloc(1654); //1654为上面内存泄漏的块号。
2、用Debug模式运行,程序自动断点在“内存块1654”分配的位置。
3、这个时候一直利用“调试”-“退出”,或快捷键“SHIFT+F11”跳转,直到看到了自己的代码。
4、检查自己在该代码中分配的内存块,是否进行了合理的释放。