| |
|
开发:
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++知识库]C/C++内存管理 |
系列文章目录文章目录一、C/C++内存分布当C/C++程序运行起来时,每个进程(正在运行的程序的一种抽象)看到的内存是一致的,就好像每个进程都在独占的使用主存一样,称为虚拟地址空间。如下: 代码段存放可执行代码和只读常量。 数据段: 数据段存放全局变量和static修饰的静态数据。 运行时堆: 相较于程序一开始运行就被指定了大小的代码段和数据段不同,堆可以在运行时进行动态的扩展和收缩。而动态内存分配的空间都在堆上。同时,堆上的空间是自下而上分配的。 共享库: 大约在虚拟地址空间中间部分是一块用来存放像C标准库和数学库这样的共享代码和数据区域。 用户栈: 再往上就是用户栈,编译器用它来实现函数调用。因为函数调用时的函数栈帧都是在栈上开辟的。和堆一样,用户栈在程序的执行期间可以动态的扩展和收缩。每当我们调用一个函数时,栈就会增长;从一个函数返回,栈就会收缩。栈是向下增长的。 内核虚拟内存: 虚拟空间顶部的区域是为内核保留的。不允许程序读写这个区域的内容或者直接调用内核代码定义的函数。它们必须通过调用内核来执行这些操作。 二、C++内存管理方式首先,在C语言中,可以通过malloc、calloc和realloc来动态分配内存,通过free释放内存。而malloc和calloc的区别就在于,calloc分配空间之后会将空间初始化为0。而realloc有两种分配方式,原地或者异地。当原地的空间足够我们扩大,就会在原地扩,否在就在异地扩。如果有需要详细了解,请参见:动态内存分配 C语言的内存管理方式在C++中也同样适用,但是有些地方会无能为力或使用起来比较麻烦,因此C++推出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。 2.1 对于内置类型
2.2 对于自定义类型先来看一段代码:
结果如下: 可以看出malloc,free和new和delete的区别,在申请自定义类型的空间时,new会调用默认构造函数,delete会调用析构函数,而malloc和free不会。 三、operator new与operator delete函数3.1 operator new与operator deletenew和delete是在用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
其实oerator new实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛出异常。同样的,operator delete最终也是通过free来释放空间的。 3.2 operator new与operator delete的类专属重载。下面代码演示了,针对链表节点的ListNode通过类专属重载operator new与operator delete,实现了链表结点使用内存池申请和释放内存,提高效率。
以往我们申请空间,每次都要像系统申请,但是这样似乎太麻烦,为了使效率提高,我们可以先申请较大的一块空间留作备用,需要时在这块空间中取就可以了。这就是内存池技术。 四、new和delete的实现原理。4.1 内置类型如果申请的是内置类型的空间,new和malloc,delete和free基本类似。new和delete申请和释放的是单个元素的空间,new[]和delete[]申请和释放的是连续的空间,而且new在申请失败时会抛出异常,而malloc会返回NULL。 4.2 自定义类型new的原理:
delete原理:
new T[N]的原理:
delete[]的原理:
五、定位new表达式(placement-new)定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。 使用格式: new(place_addreee) type或者new(place_address) type(Initializer-list) place_address必须是一个指针,Initializer-list是类型的初始化列表 定位new表达式在实际中一般是配合内存池使用。因为内存池分配的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调用构造函数进行初始化。 六、malloc/free和new/delete的区别二者的共同点是:都是从堆上申请空间,都需要用户手动释放。 不同点是:
七、内存泄漏7.1 什么是内存泄漏内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。 长期运行的程序出现内存泄漏影响很大,如操作系统、后台服务等,出现内存泄漏会导致响应越来越慢,最终卡死。 7.2 内存泄漏的分类堆内存泄露:
系统资源泄露:
7.3 如何避免内存泄漏
|
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
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年11日历 | -2024/11/23 23:53:02- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |