c++ new和delete

以下内容转载自

https://blog.csdn.net/xxpresent/article/details/53024555


说起new和delete,了解过c++的人应该都知道吧,它是用来分配内存和释放内存的两个操作符。与c语言中的malloc和free类似。

c语言中使用malloc/calloc/realloc/free进行动态内存分配,malloc/calloc/realloc用来在堆上分配空间,free将申请的空间释放掉。

malloc:

[cpp]  view plain  copy
  1. void FunTest()  
  2. {  
  3.     int *pTest = (int*)malloc(10*sizeof(int));         //开辟10个int型的空间大小  
  4.     if(pTest != NULL)  
  5.     {  
  6.         free(pTest);  
  7.         pTest = NULL;  
  8.     }  
  9. }  
calloc:

[cpp]  view plain  copy
  1. void FunTest()  
  2. {  
  3.     int *pTest = (int*)calloc(10,sizeof(int));    //分配10个int型的内存块,并将其初始化为0  
  4.     if(pTest != NULL)  
  5.     {  
  6.         free(pTest);  
  7.         pTest = NULL;  
  8.     }  
  9. }  
realloc:

[cpp]  view plain  copy
  1. void FunTest()  
  2. {  
  3.     int *pTest = (int*)malloc(10*sizeof(int));     
  4.     realloc(pTest,20*sizeof(int));   //改变原有空间大小,若不能改变则会新开辟一段空间,并将原有空间的内容                                               拷贝过去,但不会对新开辟的空间进行初始化  
  5.     free(pTest);  
  6. }  
这里要注意的一点是,为什么分配了空间之后,必须要用户手动去free掉呢,是因为malloc、calloc、realloc都是在堆上分配的,堆上分配的空间必须由用户自己来管理,如果不释放,就会造成内存泄漏。而栈上分配的空间是由编译器来管理的,具有函数作用域,出了函数作用域后系统会自动回收,不由用户管理,所以不用用户显式释放空间。

对于内存泄漏,我介绍一下我所见过的内存泄漏吧:

(1)申请内存但并未释放。

[cpp]  view plain  copy
  1. void FunTest()  
  2. {  
  3.     int *pTest1 = (int*)malloc(10*sizeof(int));  
  4.     *pTest1 = 0;  
  5. }  
(2)程序逻辑错误,这里引出两个问题。

①同一块空间释放两次,导致崩溃;

②有一块空间没有释放,以为释放了,导致内存泄漏。

[cpp]  view plain  copy
  1. void FunTest()  
  2. {  
  3.     int *pTest1 = (int*)malloc(10*sizeof(int));  
  4.     int *pTest2 = (int*)malloc(10*sizeof(int));  
  5.   
  6.     pTest1 = pTest2;  
  7.     free(pTest1);  
  8.     free(pTest2);  
  9. }  
(3)程序的误操作,将堆破坏。申请的空间不足以赋值,释放导致崩溃。

[cpp]  view plain  copy
  1. void FunTest()  
  2. {  
  3.     char *pTest1 = (char*)malloc(5);  
  4.     strcpy(pTest1,"hello world");  
  5.     free(pTest1);  
  6. }  
(4)当释放时传入的地址和分配时的地址不一样时,会导致崩溃。
[cpp]  view plain  copy
  1. void FunTest()  
  2. {  
  3.     int *pTest1 = (int*)malloc(10*sizeof(int));  
  4.     assert(pTest1 != NULL);  
  5.     pTest1[0] = 0;  
  6.     pTest1++;      //地址向后移动了一位  
  7.     free(pTest1);  
  8. }  
上述简单的介绍了一下c语言中动态内存管理的类型,下面讲解一下c++中的动态内存管理。

c++中是通过new和delete操作符进行动态内存管理的。

先用一张图简单的说明一下new和delete的含义:


记住:new和delete就像malloc和free一样,都要成对使用哦

我们再看一个这样的表达式:

[cpp]  view plain  copy
  1. string *s = new string("a value");     //分配并初始化一个string对象  
  2. string *str = new string[10];          //分配10个默认初始化的string对象  
这两个new表达式,一个是分配一个对象,一个是分配对象数组。内部实现也是截然不同。

这是string *s = new string("a value"); 这句表达式内部的实现:



我们可以看出new内部的调用顺序:(初始化一个对象时)


new内部的调用顺序:(初始化若干个对象时)


同样地,delete对象时,调用顺序为:(delete单个对象时)



delete对象时,调用顺序为:(delete多个对象时)



接下来,看一下动态内存分布图:


new和delete与malloc和free一样,都是存在堆上的。那么,二者有什么差别呢?


· 总结new/delete和malloc/free的区别和联系:

1. 它们都是动态管理内存的入口。

2. malloc/free是C/C++标准库的函数,new/delete是C++操作符。

3. malloc/free只是动态分配内存空间/释放空间。而new/delete除了分配空间还会调用构造

析构函数进行初始化与清理(清理成员)。

4. malloc/free需要手动计算类型大小且返回值为void*,new/delete可自己计算类型的大小

对应类型的指针。

5.new/delete的底层调用了malloc/free。

6.malloc/free申请空间后得判空,new/delete则不需要。

7.new直接跟类型,malloc跟字节数个数。


猜你喜欢

转载自blog.csdn.net/pyf09/article/details/80593113