简易个人博客网站源码如何设置网站图标
2026/6/20 5:03:52 网站建设 项目流程
简易个人博客网站源码,如何设置网站图标,商丘高端网站建设,网站建设前台功能复习C语言中的动态内存管理方式void test1() {int* p1 (int*)malloc(sizeof(int));free(p1);// 1.malloc/calloc/realloc的区别#xff1a;// malloc - 只分配内存#xff0c;不初始化// calloc - 分配内存并初始化为0#xff0c;参数是(元素个数, 每个元素大小)// realloc…复习C语言中的动态内存管理方式void test1() { int* p1 (int*)malloc(sizeof(int)); free(p1); // 1.malloc/calloc/realloc的区别 // malloc - 只分配内存不初始化 // calloc - 分配内存并初始化为0参数是(元素个数, 每个元素大小) // realloc - 重新分配内存可以扩大或缩小已有内存块 int* p2 (int*)calloc(4, sizeof(int)); // 分配4个int并初始化为0 int* p3 (int*)realloc(p2, sizeof(int) * 10); // 将p2的内存扩大到10个int // 这里不需要free(p2) // 因为realloc成功后原来的p2指向的内存已经被释放或移动 // 如果realloc返回新指针原指针p2不应该再被使用 free(p3); // 只需要释放新的指针p3 }malloc是分配内存不会初始化calloc是分配内存初始化为0参数元素个数每个元素的大小realloc是重新分配内存可以扩大或者缩小已有的内存在C中兼容我们的C语言所以C语言的动态内存管理在C也可以使用学习C中的动态内存管理的方法C语言内存管理方式在C中可以继续使用但是有一些地方不一定能做到并且使用起来会有一些麻烦因此C引出了自己的内存管理方式通过new和delete操作符进行动态内存管理但是我们需要注意的是malloc/free是库函数而new/delete是操作符void test1() { //C语言 malloc等是库函数 int* p1 (int*)malloc(sizeof(int)); free(p1); //C new/delete是操作符 // 动态申请一个int类型的空间 int* ptr4 new int;//写法 // 动态申请一个int类型的空间并初始化为10 int* ptr5 new int(10);//写法 delete ptr4; delete ptr5; }那么new/delete和malloc/free有没有什么区别呢如果动态申请的对象是内置类型那么用malloc和new没有什么区别如果动态申请的对象是自定义类型那么就有区别比如class A { public: A(int a0) :_a(a) { coutA()endl; } ~A() { cout~A()endl; } private: int _a; }; int main() { //C语言自定义类型开辟空间 A* p3 (A*)malloc(sizeof(A));//没有初始化 free(p3); //C自定义类型开辟空间 A* p4 new A;//调用构造函数初始化 delete p4;//调用析构函数 }new和delete不仅仅会开空间和释放空间还会调用构造函数和析构函数接下来我们用数据去看malloc和new的区别我们使用malloc没有初始化使用了new进行了初始化那我们想给new的对象传参应该怎么写呢A* p4 new A(10);//调用构造函数初始化 //我们也可以new数组 A *ptr1 new A[10];//new了10个对象调用了10次构造函数 delete[] ptr1;需要注意的是在new数组的时候delete需要[]总结对于内置类型用malloc和new没有什么区别但是使用自定义类型就有区别用malloc和new的区别是new和delete会去调用构造函数和析构含糊一定要匹配的去使用不然会造成崩溃在C中也建议去使用new和deletemalloc和free能做到的那么new和delete也能做到相反new和delete能做到的malloc和free不一定能够做到operator new 与 operator delete函数new和delete是用户进行动态内存申请和释放的操作符operator new 和 operator delete 是系统提供的全局函数new在底层调用operator new全局函数来申请空间delete在底层通过operator delete全局函数来释放空间.注意operator new 与 operator delete函数是全局的库函数他们并不是new和delete的重载我们使用new一个新对象T的时候编译器有两个做法1、申请内存调用operator new(底层其实是将malloc封装)2、调用库函数在delete的时候编译器会发生1、调用T的析构函数2、调用operator delete(底层其实是将free封装)我们平时写malloc会这样子去写int main() { //malloc失败返回NULL char* p1 (char*)malloc((size_t)2*1024*1024*1024); if(p1NULL) { printf(malloc fail\n); } else { printf(malloc success\n); } return 0; }那么new操作符在new失败的时候会怎么去处理呢int main() { char* p2 new char[0x7fffffff]; //并没有执行 if(p2NULL) { printf(new fail\n); } else { printf(new success\n); } return 0; }可以看到new失败的时候并没有去执行if语句我们说过malloc和new不一样new在申请空间失败的时候会抛出异常下面我们看一段抛出异常的代码int main() { try { void* p1 new char[1024 * 1024 * 1024]; cout p1 endl; void* p2 new char[1024 * 1024 * 1024]; cout p2 endl; void* p3 new char[1024 * 1024 * 1024]; cout p3 endl; } catch (const exception e) { cout e.what() endl;//抛出异常 } return 0; }operator new其实就是对malloc的封装如果申请内存失败了抛出异常封装malloc抛出异常operator delete也是对free进行封装通过上述两个全局函数的例子我们可以发现operator new实际也是通过mallloc来申请空间如果malloc申请空间成功就直接返回否则执行用户提供的空间不足应对措施如果用户提供该措施就继续申请否则抛出异常。operator delete 最终是通过free来释放空间的new和delete的实现原理内置类型如果申请的是内置类型的空间new和mallocdelete和free基本类似不一样的地方是new/delete申请释放的是单个元素的空间new[]和delete[]申请的是连续空间而且new在申请空间失败的时候会抛出异常malloc会返回NULL自定义类型new的原理1、调用operator new函数申请空间2、在申请的空间上执行构造函数完成对象的构造delete的原理1、在空间上执行析构函数完成对象中资源的清理工作2、调用operator delete 函数释放对象的空间new T[N]的原理1、调用operator new[]函数在operator new[]中实际调用operator new函数完成N个对象空间的申请2、在申请的空间上执行N次构造函数delete[]的原理1、在释放的对象上执行N次析构函数完成对N个对象的资源清理2、调用operator delete[]释放空间实际在operator delete[]中调用operator delete来释放空间int main() { Stack st; Stack* ps new Stack; delete ps; retunr 0; }定位new表达式(placement-new)定位new表达式是在已分配的原始内存空间中调用构造函数初始一个对象使用格式new (place_address) type或者newplace——addresstypeinitializer-listplace_address必须是一个指针initializer-list是类型的初始化列表使用场景定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化所以如果是自定义类型的对象需要使用new的定义表达式进行显示调构造函数进行初始化。构造函数调用什么时候自动调用呢1、创建对象时2、new一个对象时class A { private: int _a; public: A(int a 0)//构造函数 :_a(a) { cout _a A(int a 0)构造函数 endl; } ~A()//析构函数 { cout _a ~A()析构函数 endl; } }; int main() { A* ptr1 (A*)malloc(sizeof(A)); //显示调用构造函数用来初始化一块已经开辟好的空间 new(ptr1)A(10); //显示调用析构函数 ptr1-~A(); //释放ptr1指向的空间 free(ptr1); A* ptr2 (A*)operator new(sizeof(A)); //显示调用构造函数用来初始化一块已经开辟好的空间 new(ptr2)A; //显示调用析构函数 ptr2-~A(); //释放ptr2指向的空间 operator delete(ptr2); return 0; }ptr1现在指向的只不过是与A对象相同大小的一段空间还不能算是一个对象因为构造函数没有执行显式对一块空间调用构造函数初始化new(ptr1) A;如果我们复制一份a数组到另外一块空间b数组怎么复制呢也许你想的是这样通过一个循环来拷贝int main() { A a[5]; //复制一份a数组到另外一块空间b A* pb1 new A[5]; for(int i 0;i5;i) { b[i]a[i]; } coutendl; //代价大 构造赋值 return 0; }但是这样代价大经过了构造赋值重载那么能不能直接构造呢通过定位new表达式就可以直接构造int main() { A a[5]; //能不能直接构造 A *pb (A*)malloc(sizeof(A)*5); for(int i 0;i5;i) { new(pbi)A(a[i]); }//只有构造 return 0; }常见面试题malloc/free和new/delete的区别1、特点和用法malloc和free是函数new和delete是操作符malloc申请空间时需要手动计算空间大小并传递new只需在后面跟上空间的类型即可如果是多个对象[]中指定对象个数即可malloc的返回值是void*在使用时需要强转new不需要因为new后面跟的是空间的类型2、底层原理区别申请自定义类型对象时malloc/free只会开辟空间不会调用构造函数和析构函数而new在申请空间后会调用构造函数完成对象的初始化delete在释放空间前会调用析构函数完成空间中资源的清理3、处理错误的方式malloc申请空间失败时返回NULL因为使用时需要判空new不需要但是new需要捕获异常内存泄漏什么是内存泄漏呢在堆上申请了的空间在我们不用了以后也没有释放就存在内存泄漏因为你不用了也没有还给系统别人也用不了。俗话说占着茅坑不拉屎那么我们如何预防内存泄漏呢1、智能指针2、内存泄漏的检测工具

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询