C++ delete的时效问题

来源:互联网 发布:qemu ubuntu arm 编辑:程序博客网 时间:2024/05/17 03:55

测试示例:

[cpp] view plain copy
  1. #include <iostream>  
  2. using namespace std;  
  3. int main()  
  4. {  
  5. int *map;  
  6.     int i=10;  
  7.     while(i--)  
  8.     {  
  9.     map=new int[20];  
  10.     map[i]=i;  
  11.     cout << map[i]<<endl;//1  
  12.     delete [] map;  
  13.     cout << map[i]<<endl;//2  
  14.     }  
  15. }  
结果:

输出结果
9
9
8
8
7
7
6
6
5
5
4
4
3
3
2
2
1
1
0
0


疑问:

delete释放之后,内容并不是立即回收的吗?


解析:

内存被释放后 表示这块儿内存可以被操作系统重新分配,但是指针还是指向这块儿内存的。虽然指针还是指向原来的位置,但是那一块内存随时都可能会被回收,因此输出的结果是具有不确定性的。所以我们在delete的同时 也要将指针置为NULL 这样在下一次调用该指针时,用if(NULL == p)才能判断出指针的状态,避免使用野指针。


那么,delete之后能不能立即生效呢?


答案肯定是可以的,不过这个也是和操作系统有关的。


在Windows操作系统下,我们通过调用相关的Windows API即可立即让操作系统进行内存回收。

[cpp] view plain copy
  1. // test.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5.   
  6.   
  7. #include <iostream>    
  8. #include <windows.h>    
  9. #include <psapi.h>    
  10. #pragma comment(lib,"psapi.lib")    
  11. using namespace std;  
  12. void showMemoryInfo(void)  
  13. {  
  14.     HANDLE handle = GetCurrentProcess();  
  15.     PROCESS_MEMORY_COUNTERS pmc;  
  16.     GetProcessMemoryInfo(handle, &pmc, sizeof(pmc));  
  17.     cout << "内存使用:" << pmc.WorkingSetSize / 1000 << "K/" << pmc.PeakWorkingSetSize / 1000 << "K + " << pmc.PagefileUsage / 1000 << "K/" << pmc.PeakPagefileUsage / 1000 << "K" << endl;  
  18. }  
  19. int main(int argc, char* argv)  
  20. {  
  21.     showMemoryInfo();  
  22.     cout << "回收所有可回收的内存" << endl;  
  23.     EmptyWorkingSet(GetCurrentProcess());  
  24.     showMemoryInfo();  
  25.     cout << "开始动态分配内存" << endl;  
  26.     char* buf[1];  
  27.     for (int i = 0; i < sizeof(buf) / sizeof(char*); i++)  
  28.     {  
  29.         buf[i] = new char[102400];  
  30.         showMemoryInfo();  
  31.     }  
  32.     cout << "开始释放内存" << endl;  
  33.     for (int i = 0; i < sizeof(buf) / sizeof(char*); i++)  
  34.     {  
  35.         delete buf[i];  
  36.         buf[i] = NULL;  
  37.         showMemoryInfo();  
  38.     }  
  39.     cout << "回收所有可回收的内存" << endl;  
  40.     EmptyWorkingSet(GetCurrentProcess());  
  41.     showMemoryInfo();  
  42.     return 0;  
  43. }  

结论:delete之后只是程序告诉操作系统这一块内存我需要了,操作系统可以随时回收。至于什么时候回收这一块内存,就是和操作系统有关了,我们无法知道,或者会在很久后回收,或者因为比较着急会立即回收,是具有不确定性的。因此,在delete之后我们要养成立即将指针置为NULL的好习惯!