一、new与malloc,free与delete的异同
(1)相同点
都用于动态内存的申请、释放
(2)不同点
(3)free为什么不需要指定大小
系统在分配内存时除了分配指定的内存空间外,还要分配用于保存内存空间大小等信息。所以内存释放时不再需要再指定释放多大的内存空间,只需要指定该块内存空间的首地址即可。
具体测试
在红框的位置,出现的是申请内存的大小(经过了多次测试)。
二、new、delete、malloc、free的一些测试
之前使用new和delete时发现的一些有趣事
1 typedef char* p_char; 2 #define d_char char * 3 class T { 4 public: 5 int a; 6 T() { a = 10; cout << "constructor" << endl; } 7 ~T() { 8 cout << "destructor" << endl; 9 } 10 }; 11 12 int main() 13 { 14 const int NUM = 3; 15 T* p1 = new T[NUM]; 16 cout << hex << p1 << endl; //输出P1的地址 17 delete p1; 18 }
这是我写的错误代码,一开始认为只会是内存泄漏,但是实际情况是段错误,输出为
以下是我的进行的思考
(1)malloc、free的测试
根据上述图片出现的情况,实际输出了一次析构函数后出现段错误,我将问题定位在delete的第二步,operator delete时出现错误,测试以下代码。
1 int* pp = (int *)malloc(10 * sizeof(int)); 2 pp++; 3 free(pp);
发现也会报段错误;
推断free只能从申请的首地址进行释放内存,应该是和操作系统内存管理有关系,比如free是从free list中读取的内存信息,才能准确释放内存,所以上述代码出现段错误;
所以delete一个new的数组,从p1的位置调用析构函数没有错误,但是free时,没有找到正确的申请内存首地址(应该是p1-4),所以free失败,产生段错误;
(2)new、delete测试
这样测试完,后我将T类变成基本数据类型,发现没有异常;
1 int * a = new int[10]; 2 delete a;
查阅、咨询别人,得出结论是,系统申请基本数据类型,并不会多申请4个字节的内存所以不会报段错误,多申请4个字节是为了记录class调用的析构函数次数;
然后又测试了以下代码
1 class T { 2 public: 3 int a; 4 T() { a = 10; cout << "constructor" << endl; } 5 //~T() { 6 // cout << "destructor" << endl; 7 //} 8 }; 9 10 int main() 11 { 12 const int NUM = 3; 13 T* p1 = new T[NUM]; 14 cout << hex << p1 << endl; //输出P1的地址 15 delete p1; 16 }
惊奇的发现,也并没有报段错误;
查阅资料后,推断travial destructor的类应该不会调用析构函数,或者说被编译器优化掉了;
(3)得出结论
最后感谢以下大佬的博客
https://blog.csdn.net/shandaliuyan/article/details/5930719
https://www.cnblogs.com/hezhixiong/p/4535534.html
感谢阿秀大佬
https://gitee.com/Rosasp/CPlusPlusThings
原文:https://www.cnblogs.com/cutelife/p/14803675.html