确切的说,在C++中对内存的管理是挺复杂的,申请内存的同时也必须记得释放内存,new匹配delete, new[]匹配delete[].还有更困难的是在涉及到组模(Module),这点暂不讨论,等我搞清楚后会和大家分享。现在先说一下CMemoryState,如有什么不足之处,或者是错误的地方,请各位看官不吝赐教,谢谢。
在MFC中,可以使用CMemoryState检测内存泄露,内存的泄露是由于程序在内存分配和检索中错误使用了C++的new或delete操作符导致的。我们可以创建CMemoryState对象,来快速查看当前内存的分配情况,不多说了,直接代码吧!
1. 没有 delete.
1. CMemoryState oldMem, newMem, difMem;
2. oldMem.Checkpoint(); // 检测当前的内存使用情况
3. char* c = new char[6];
4. TRACE0("1-------------------/n");
5. oldMem.DumpAllObjectsSince(); // oldMem就检测到这里
6. TRACE0("2-------------------/n");
7. newMem.Checkpoint(); // 没有delete[] c
8. if (difMem.Difference(oldMem, newMem)) // 比较
9. {
10. TRACE0("Memory Lack!/n");
11. }
12. TRACE0("3-------------------/n");
13. difMem.DumpStatistics(); // 在Output中打印结果
- TRACE0("4-------------------/n");
Output:
1-------------------
Dumping objects ->
e:/test/ccing.cpp(101) : {140} normal block at 0x003B8A10, 6 bytes long.
Data: < > CD CD CD CD CD CD
Object dump complete.
2-------------------
Memory Lack!
3-------------------
0 bytes in 0 Free Blocks.
6 bytes in 1 Normal Blocks.
0 bytes in 0 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 0 bytes.
Total allocations: 6 bytes.
4-------------------
//注意以下内容为编译器输出
Detected memory leaks!
Dumping objects ->
e:/test/ccing.cpp(101) : {140} normal block at 0x003B8A10, 6 bytes long.
Data: < > CD CD CD CD CD CD
Object dump complete.
大家可以看到,申请多少了内存,内存被分配到什么地方都有说明,最后还提示内存泄露!
2. 加入delete
1. delete[] c; // 其他都不变
2. newMem.Checkpoint(); // 加入delete[] c
Output:
2-------------------
3-------------------
0 bytes in 0 Free Blocks.
0 bytes in 0 Normal Blocks.
0 bytes in 0 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 0 bytes.
Total allocations: 6 bytes.
4-------------------
都释放干净了。
3. 测试一些数据类型.
(1).内置数据类型
1. oldMem.Checkpoint(); // 检测当前的内存使用情况
2. int i = 1; // 其他都不变
3. double b = 2;
4. char a = '1';
- char ch[6];
Output:
2-------------------
3-------------------
0 bytes in 0 Free Blocks
0 bytes in 0 Normal Blocks.
0 bytes in 0 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 0 bytes.
Total allocations: 0 bytes.
内置类型的没有构造,且不能对C的malloc/free.GlobalAlloc/GlobalFree或LocalAlloc/LocalFree的检测!
(2).C++类型 string
1. oldMem.Checkpoint(); // 检测当前的内存使用情况
- string s = "123456";
Output:
2-------------------
3-------------------
0 bytes in 0 Free Blocks
0 bytes in 0 Normal Blocks.
0 bytes in 0 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 0 bytes.
Total allocations: 0 bytes.
这是STL的事情,STL有一套自己的内存的管理的方法。
(3).对MFC类型 CString
1. oldMem.Checkpoint(); // 检测当前的内存使用情况
- CString str = _T("123456");
Output:
1-------------------
Dumping objects ->
f:/sp/vctools/vc7libs/ship/atlmfc/src/mfc/strcore.cpp(141) : {147} normal block at 0x003B8CC0, 23 bytes long.
Data: <, ?x > 2C 08 3F 78 06 00 00 00 06 00 00 00 01 00 00 00
Object dump complete.
2-------------------
Memory Lack!
3-------------------
0 bytes in 0 Free Blocks.
23 bytes in 1 Normal Blocks.
0 bytes in 0 CRT Blocks.
0 bytes in 0 Ignore Blocks.
0 bytes in 0 Client Blocks.
Largest number used: 0 bytes.
Total allocations: 23 bytes.
4-------------------
// 没有 Detected memory leaks! 因为CString对象在适当的时候释放
大家可以看到,这是MFC自己的事情,2块内存相比,存在差异,但是并没有提醒Detected memory leaks!
总结:我们在使用内存检测的时候最好就是检测new 和delete 不要检验其他的数据类型。也可以检测某个函数调用完后内存的使用情况