前言
大家好,这里是YY的带你手把手掌握C++系列。大部分知识点都含有【特性介绍】【使用场景】【注意要点】【易混淆点】【代码演示】【画图演示】由于C++体系之庞大,所以该系列以分P形式更新!本篇博客为P2!
大家可以通过本篇博客查找C++相关知识点和使用场景。欢迎大家收藏,以备以后使用。希望能帮助到大家!
欢迎大家点赞评论,留下您的宝贵意见!对作者而言是莫大的激励!谢谢大家!
本P即P2的主要知识点有:【C/C++的内存管理】【】【】【】【】【】【】【】【】【】【】【】【】【】持续更新中
P1的主要知识点有:【缺省函数】【命名空间域】【函数重载】【引用】【C++中的NULL与空指针区别】【内联函数】【类】【This指针】【const成员/成员函数】【static静态成员 】【explicit关键字】【友元】【内部类】【匿名对象(即临时对象)】【初始化列表】【类的六个默认成员函数】如有需要可以前往YY的带你手把手掌握C++系列(P1)查看!
另有C语言专栏:涵盖C语言基础与拓展知识,欢迎大家前往阅读!订阅!
【1】指针【2】数组【3】操作符4】动态内存管理【5】内存函数大全【6】文件操作函数
【7】程序的编译链接预处理详解【8】数据在内存中的处理
目录
一.C/C++的内存管理
1.C/C++的内存分布规则
一.易错点:数组存储字符串和指针指向字符串,解引用后所在的位置不同(含例题)
2.C/C++的内存管理方式
一.C/C++的内存管理
1.C/C++的内存分布规则
- 栈又叫堆栈--非静态局部变量/函数参数/返回值等等,栈是向下增长的。
- 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口 创建共享共享内存,做进程间通信。(Linux课程如果没学到这块,现在只需要了解一下)
- 堆用于程序运行时动态内存分配,堆是可以上增长的。
- 数据段--存储全局数据和静态数据。
- 代码段--可执行的代码/只读常量。
图示:
一.易错点:数组存储字符串和指针指向字符串,解引用后所在的位置不同(含例题)
- *char2数组所在的位置是栈,是位于代码段(常量区)"abcd\0"的一份拷贝;
- pChar3是一个指向代码段(常量区)"abcd\0"的一个指针变量,由于其具有常性,所以要加上const;
图示:
2.C/C++的内存管理方式
PS:C的内存管理有malloc/calloc/realloc/free(可见博主C专栏:动态内存管理)
引入:C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。(一般C与C++内存管理不混用)
一.使用new和delete操作符的使用规范
注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用 new[]和delete[],要匹配起来使用。(如果new后接free,无论是否是对同一块空间的操作,都容易报错)
代码演示:
//报错 int* p3 = (int*)malloc(sizeof(int)); // C int* p4 = new int; free(p4); 对开辟同一块空间操作,不匹配 delete p3; //报错 int* p3 = (int*)malloc(sizeof(int)); // C int* p4 = new int; free(p3); 对开辟不同一块空间操作,不匹配 delete p4;
二.new和delete对内置类型的具体使用场景
使用场景:
- 申请一个int类型空间(默认为0)
- 申请一个int类型空间,并初始化为10
- 申请10个int类型空间
- 申请10个int类型空间,并分别初始化
代码演示:
void Test() { // 动态申请一个int类型的空间 int* ptr4 = new int; // 动态申请一个int类型的空间并初始化为10 int* ptr5 = new int(10); // 动态申请10个int类型的空间 int* ptr6 = new int[10]; // 动态申请10个int类型的空间,并初始化 int* ptr7 = new int[10]{1,3,4}; delete ptr4; delete ptr5; delete[] ptr6; }
三.new和delete对自定义类型的具体使用场景
使用场景:有一个自定义类型A,他的初始化列表需要传入两个参数
- 申请一个空间给A(默认为0)
- 申请一个4个空间给4个A,分别初始化
代码演示:
void test() { A* p1 = new A(1,1); delete p2; //错误写法:不完全初始化 A* p2 = new A[4]{ A(1,1),A(2,2),A(3,3)}; A* p2 = new A[4]{ A(1,1),A(2,2),A(3,3),A(4,4) }; delete[] p2; }
四.new/delete与malloc/free的底层区别(自定义类型演示)
new/delete 和 malloc/free根本区别:
- new的底层其实也是malloc,与malloc不同之处在于他会调用拷贝构造
- delete的底层其实也是free,与free不同之处在于他会调用析构函数
实例分析:(顺序)
- 在下图中,new了一个栈Stack,其实底层是先malloc个空间给Stack(自定义类型),再调用它的拷贝构造(_array指向的新空间);
- 当delete栈Stack时,先调用析构函数(free掉刚刚_array指向的新空间),再free掉Stack所处的空间;
- PS:如果不是这样,而是先free掉Stack的空间,那么_array指向的新空间将无法被p1找到,造成内存泄漏
图演示:
五. new/delete与malloc/free在使用失败时的区别
C++是一门面向对象的语言,处理失败时,不喜欢用返回值,更喜欢用抛异常