| |
|
开发:
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++开辟的内存方式(new/delete),深入理解new和delete。 一、C/C++中的内存分布1、内存分布的基础知识在计算机存储中存在怎么几个区域需要我们去了解
?2、内存分布的一道面试题下面看一段代码,在细细体会一下一个代码中的变量都存储在计算机的那些位置:
我们可以对比上面的图来理解这道题:
二、C++的内存管理方式1、C++的动态内存开辟和释放以前在C语言中我们就学习跟动态内存开辟的几个函数:malloc函数和calloc及realloc函数这些函数的区别就不在多说了(感兴趣的小伙伴可以查看我之前写的博客)。 虽然C++在语法上是兼容C语言的,但是因为某些原因(下面会说),C++又用关键字来new来开辟动态空间,用delete关键字来释放动态开辟的空间。 这里通过调试可以看到new位p开辟了一个整形的空间,但是p中存在的是一个随机值,那么又该如何去初始化呢? ?这里我们只要在括号中传我们想要初始化的值就可以了。
2、new/detele和malloc/free的区别操作内置类型
上面代码p1和p2开辟的动态空间有什么区别吗? ?我们观察到对于内置类型来说new和malloc开辟的动态空间基本类似,不同的地方是: new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。 操作自定义类型
?将代码运行起来会出现什么情况呢? ?这里我们发现用new/delete不仅为了类A开辟了动态空间,new调用了类构造函数delete调用了析构函数,而malloc函数是没有这给功能的。
malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地 new/detele和malloc/free的区别(从用法,和底层实现)
三、深入理解new和delete1、new/delete底层机制的实现我们知道new和delete是用来动态开辟和释放空间的操作符(关键字,那么他们又是如何去实现呢? 这就不得不说operator new 和operator delete是 系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过 operator delete全局函数来释放空间。 operator new函数 这里大家要主要,new不是重载,而是一个全局函数? 这里来看一段代码的反汇编: ? ?在我们用new开辟动态空间,最重要的是调用了二个函数,这里我们重点关注operator new函数,那这个函数的底层又是什么呢? ?这里可以看到底层是用的malloc开辟空间的,那有小伙伴可能就要问了,为什么不直接用malloc开辟而要弄出一个operator new函数来进行封装一下呢?因为C++语言是面对对象的语言,而且new开辟空间后是不需要检测开辟是否成功的,但是需要抛异常(以后会为大家分享),所以要用operator new函数进行封装一下这样才符合C++面对对象出来错误的方式。 operator delete函数 这个函数的出现也是为了封装delete,下面我们直接看他的底层是如何实现的: ?从上面我们可以看出opertaror底层的实现也是调用了free的。 总结:
2、定位new表达式定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。 ?使用格式: new (place_address) type或者new (place_address) type(initializer-list) place_address必须是一个指针,initializer-list是类型的初始化列表 使用场景: 定位new表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。 来看下面这段代码来理解一下:
先来看到指针p1,我们用malloc来开辟的一个动态空间来存储来存放类的空间,但是他现在还能说是建立了一个对象,因为这里析构函数是没有执行的,这时候我们就可以用new的定位表达式主动调用析构函数(我们知道析构函数以前在类外是不能主动调用的)。 对于p2指针来说我们是用operator new(new关键字的底层实现,其实也就是malloc)来开辟动态空间的,这里在new(p2)A(10),不仅仅调用来析构函数,还将类中成员变量a初始化为10。 ?3、内存泄漏什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内 存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对 该段内存的控制(也就是说我们没有指针指向这里了),因而造成了内存的浪费。 内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现 内存泄漏会导致响应越来越慢,最终卡死。 内存泄漏分类:
你们内存泄漏既然如此后果既然如果严重,那么我们有什么方法检测出来吗? 其实是有的在vs下,可以使用windows操作系统提供的_CrtDumpMemoryLeaks() 函数进行简单检测,当我们调试到该位置,在输出窗口:该函数只报出了大概泄漏了多少个字节,没有其他更准确的位置信息。 ?这时候有处不大,还是要我们去找哪里出现了内存泄漏(毕竟谁会承认自己写出了dug),而且如果工程比较大,内存泄漏位置比较多,不太好查时 一般都是借助第三方内存泄漏检测工具处理的(这里检测的工具就不在说了,种类有些多,在不同的操作系统检测工具都不同)。 总结:
|
|
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图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/11 12:53:24- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |