IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 《C++》动态内存管理 -> 正文阅读

[C++知识库]《C++》动态内存管理

一、本章重点

1、介绍c/c++内存分布

2、回顾malloc、calloc、realloc、free

3、介绍new、delete操作符

4、分析new/malloc和delete/free的区别

5、介绍定位new

6、浅谈内存泄露

二、c/c++内存分布情况

了解c语言的都知道内存一般被划分为栈区、堆区、数据段、代码段

以下图片是一个内存分区意向图(地址从高到低,栈区的地址最高),由于不想涉及系统,其实在栈区之上还有个内核空间(用户不可进行读写),在栈区和堆区之间还有一个内存映射区(该区域的作用会在系统章节详细介绍)。

?栈区:一般存储局部变量、函数参数。使用习惯是先使用高地址的空间,再使用低地址空间,释放空间时,先释放低地址,再释放高地址。一般栈区的大小在8m左右。

堆区:由程序员自由操作的内存空间,可以从堆区进行申请和释放空间,c语言申请堆区用malloc、calloc、realloc,释放使用free。如果使用完堆区内存之后,不释放空间会导致内存泄露,造成电脑卡顿。当然在程序终止之后,系统会自动回收。但如果程序24小时一直在跑,用完不释放将造成比较大的后果。还需要注意的是,申请的空间释放时必须全部释放,不能只释放一部分,也不能重复释放堆区内存。一般堆区大小在1G左右。

数据段:一般存储全局变量、静态变量,因此也有人称之为全局区/静态区。

代码段:一般存储只读常量、可执行代码。

三、回顾malloc、calloc、realloc、free

?

malloc用来在堆区申请空间,calloc也是在堆区申请空间,它们唯一的区别是calloc在申请空间之后同时会初始化为0。需要知道的是malloc和calloc申请空间失败时返回null

realloc用来调整申请的空间,一般用来实现动态的顺序表。

调整分为两种情况:

1、在原空间调整

2、释放原空间,重新开辟一块新的空间。

free用来释放申请的堆区内存。如果释放的内存指向空,则什么也不会发生。

四、介绍new、delete操作符

一、malloc和new

?new是一个操作符,用法:

1、new+类型,返回的是对应类型的指针。

2、new+类型[size],返回的是这块空间的首元素的地址。

咋一看,new和malloc好像没什么区别,都不会对内置类型进行初始化,但遇到自定义的类型,new可比malloc好多了。

?可以看出,new申请空间的同时会调用构造函数进行初始化,而malloc只是开空间。

还有就是new申请空间失败时会抛异常,而malloc则返回的是null。具体什么是异常,后面会出对应的章节进行介绍。对比new和malloc之后,我们也可以猜想出,new底层或许调用了malloc。确实是这样的,new操作符调用了operator?new函数,它是一个全局函数。而operator?new函数调用了malloc,同时用抛异常的方式处理申请空间失败。换言之,new操作符是operator new函数和构造函数的组合。

二、free和delete

delete的使用方法:

如果p是单个元素的地址(new +?类型)

使用delete p释放空间

如果p是多个元素的首地址(new+?类型 [ ])

使用delete [ ] p释放空间

?

free是用来释放堆区内存的,delete也是如此。只不过delete在释放空间之前会调用析构函数。delete和new一样,底层会调用operator?delete函数,该函数调用的是free。换言之,delete是free+析构函数的组合。

需要注意的是delete?和?new配对,delete[]和new[]配对,如果用delete去释放new[]的空间可能会导致不良的后果,注意这里是可能,一般内置类型不会有影响,建议一定要配对使用。

五、定位new

什么是定位new?简单来说就是显示的调用构造函数初始化申请的空间,一般配合内存池使用。那什么是内存池呢?简单来说就是提前向系统申请的一大块未初始化的空间,因为频繁向系统申请空间会影响效率,然后我们需要空间的时候就去内存池去切一小块空间来使用。

但切的空间是未初始化的,这时候我们就需要用定位new来初始化内存池要来的空间。

首先,如何显示调用构造函数?下面这种写法可行吗?

?化红线了,显然不行,构造函数并不能向其他成员函数那样显示的调用,而要使用定位new。

使用格式:

new(ptr)type或者new(ptr)type(initializer-list)

其中ptr是一个指针,type为类型,initializer-list为初始化列表。

?我们也可以传参调用,如下。

我们在来强化一下:

new =?operator?new +?构造函数

delete =?析构函数+ operator delete

?

六、浅谈内存泄露

什么是内存泄露?是内存丢了?还是指针丢了?

答:指针丢了。

内存泄露本质就是一块空间你使用完之后,没有释放该空间而导致内存“泄露了”。

但如何避免内存泄露呢?

1、使用检测内存泄露工具(很多工具不靠谱或者收费昂贵)

2、养成良好的代码素养,规范编码习惯。

3、采用RAII思想或者智能指针来管理资源。

总结:内存泄漏非常常见,解决方案分为两种:1、事前预防型。如智能指针等。2、事后查错型。如泄漏检测工具。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-07-20 18:34:21  更:2022-07-20 18:35:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 12:57:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码