C++动态内存管理

来源:互联网 发布:内存条js 编辑:程序博客网 时间:2024/05/22 23:42

1、malloc/free和new/delete之间关系和差异。

C通过malloc/free来管理动态内存,而C++通过new/delete管理动态内存。

malloc/free的使用方法与new/delete有所不同。

malloc/free:

[plain] view plain copy
  1. int main()  
  2. {  
  3.         int *p=(int *)malloc(sizeof(int));  
  4.           
  5.         free p;  
  6.         return 0;  
  7. }  
malloc的函数原型为void *malloc(size_t size)

new/delete:

[plain] view plain copy
  1. int main()  
  2. {  
  3.          int *p=new int;  
  4.   
  5.          delete p;  
  6.          return 0;  
  7. }  
new没有函数原型,因为new和delete都是C++中的关键字

总结它们之间的关联与区别:

(1)它们都是用来管理动态内存的。

(2)new/delete,malloc/free都要成对出现,否则会造成内存泄漏的问题。

(3)malloc函数在使用时需要指定开辟空间大小,而且因为malloc函数返回值是void*,所以需要强制转换。

而new则会自己及计算空间大小,返回对应类型指针。

(4)malloc/free只负责开辟空间释放空间,而new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理(清理

成员)。

(5)malloc/free是C的库函数,而new/delete是C++的关键字。

2、剖析new/delete、new[]/delete[]到底做了些什么事情。

在C++中,new/delete开辟对象空间,new[]/delete[]开辟对象数组空间。

new[]的方括号中是数组中对象的个数(N),使用new[]开辟空间时,不仅要开辟N个空间,还需要在这N个空间之前开辟4个字节的空间,

用来存放N,以此来告诉编译器要调用多少次构造函数,多少次析构函数。这4个字节非常重要。

[plain] view plain copy
  1. int main()  
  2. {  
  3.            int *p1=new int;          //类型  
  4.            int *p2=new int(3);     //初始化  
  5.            int *p3=new int[3]; }    //数组个数  
(1)new做了两件事:

a. 调用operator new分配空间。

b. 调用构造函数初始化对象。

(2)delete也做了两件事

a. 调用析构函数清理对象

b. 调用operator delete释放空间

(3)new[N]

a. 调用operator new分配空间。

b. 调用N次构造函数分别初始化每个对象。

(4)delete[]

a. 调用N次析构函数清理对象。(思考这里怎么N是怎么来的?)

b. 调用operator delete释放空间。

我们可以用图表示出来-------


3、实现NEW_ARRAY/DELETE_ARRAY宏,模拟new[]/delete[]申请和释放数组。

通过自己编写代码实现对于对象数组的开辟空间和释放空间,代码如下:
[plain] view plain copy
  1. #define _CRT_SECURE_NO_WARNINGS 1  
  2. #include<iostream>  
  3. using namespace std;  
  4. class Array  
  5. {  
  6. public:  
  7.     Array(size_t size = 10)              //数组类的构造函数  
  8.         : _size(size)  
  9.         , _a(0)  
  10.     {  
  11.         cout << "Array(size_t size)" << endl;  
  12.         if (_size > 0)  
  13.         {  
  14.             _a = new int[size];  
  15.         }  
  16.     }  
  17.     ~Array()                   //析构函数  
  18.     {  
  19.         cout << "~Array()" << endl;  
  20.         if (_a)  
  21.         {  
  22.             delete[] _a;  
  23.             _a = 0;  
  24.             _size = 0;  
  25.         }  
  26.     }  
  27. #define NEW_ARRAY(PTR,TYPE,N)\                                        //利用宏开展实现new[]  
  28.     do                                         \  
  29.     {                                          \  
  30.     PTR = (TYPE*)operator new(sizeof(TYPE)*N+4); \       //调用operator new函数开辟N个TYPE类型的空间,还要另外开辟4个字节空间  
  31.     (*(int*)PTR) = N;                          \         //在开辟的4个字节空间中存放N,即对象个数  
  32.     PTR = (TYPE*)((int*)PTR + 1);              \         //将PTR指针后移到对象空间  
  33.     for (size_t i = 0; i < N; ++i)             \         //对对象数组空间调用构造函数  
  34.     new(PTR + i)TYPE;                          \  
  35.     }while (false);                            \  
  36.   
  37. #define DELETE_ARRAY(PTR,TYPE)\  
  38.     do{                                        \  
  39.     size_t N = *((int*)PTR - 1);               \          //在NEW_ARRAY中PTR指向对象数组,现在将4个字节处的值取出来赋给N  
  40.     for (size_t i = 0; i < N; ++i)             \          //调用析构函数释放空间  
  41.         PTR[i].~TYPE();                        \  
  42.     PTR = (TYPE*)((char*)PTR - 4);         \           //开辟的空间还有4个字节未释放,将PTR前移,调用operator delete释放  
  43.     operator delete(PTR);                  \  
  44.     } while (false);  
  45. private:  
  46.     int*_a;  
  47.     size_t _size;  
  48. };  
  49.   
  50. int main()  
  51. {  
  52.     Array*p1;  
  53.     NEW_ARRAY(p1, Array, 10);  
  54.   
  55.     DELETE_ARRAY(p1, Array);  
  56.     system("pause");  
  57.     return 0;  
  58. }  
原创粉丝点击