| |
|
开发:
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语言】零基础教程——动态内存管理 |
目录 ????????????????那如果malloc函数开辟失败会怎么样呢? ????????? ? ? ? 在C语言中有这么一个定义好的值:INT_MAX ????????calloc函数有什么特点呢?和malloc函数有什么区别呢? ????????例子:在malloc开辟的40个字节的空间扩容到80个字节的空间 1.为什么存在动态内存分配1.1我们熟知的开辟内存方式有????????在栈区上开辟4个字节的空间
????????在栈区上开辟16个字节的连续空间
?1.2已知的开辟方式有以下两个特点
1.3原因? ? ? ? 但是,有些时候,我们要通过运行程序才能知道数组需要的空间大小,亦或是在程序运行期间,需要增大数组的空间,这又该如何去做呢? ?????????这就不得不引入动态内存开辟的概念了~ ?2. 动态内存函数的介绍2.1 malloc????????C语言提供了来自stdlib.h头文件中动态内存开辟的函数
此函数会向?堆区 申请一段连续可用空间,开辟成功则返回开辟空间的起始位置的地址? malloc函数的特点? ? ? ? 开辟成功,返回这块空间的指针; ? ? ? ? 开辟失败,返回一个NULL指针,所以每一次开辟空间一定要检查; ? ? ? ? 返回类型为void* ,所以需要我们根据自己的需求,将返回的指针强制类型转化成我们需要的指针; ? ? ? ? 若size的单位是字节,若参数为0,malloc是未定义的,取决于编译器; malloc函数具体使用举个例子:开辟10个整形的空间,并分别赋值0~9的数字
????????这时候可能有同学可能会问了: ????????那如果malloc函数开辟失败会怎么样呢?演示一波~ ? ? ? ? 在C语言中有这么一个定义好的值:INT_MAX?这是什么东西呢? ? ? ? ? 叫整形最大值,有多大呢? 转到定义来看看: ?不得了,是一个21亿多的一个数字,这时候,让malloc函数开辟这么打一个空间试试? 嗯...好吧没想到电脑内存还蛮大的,开辟出来了... ?这样,咱来个INT_MAX*INT_MAX 走~ ?还没运行,就已经提醒你了哈哈哈。 一个开辟空间失败的错误示范; 还有一个点: 什么是栈区,堆区?? ? ? ? 内存里面分为三个区,就是栈区,堆区,静态区(实际上还有很多其他区,主要讲这几点),栈区是用来存放临时变量的,变量空间定义好就不能再变了,而malloc、calloc、realloc这几个函数就会在堆区上开辟空间,定义好后根据需求,可以继续改变变量所占空间的大小,静态区用来存放全局变量;(如下图) 细致一点就如下图: ? ????????有没有思考过这样一个问题? ? ? ? ?即使一个空间用完了,退出程序,系统会自动回收空间,?但如果一个空间用完了,不想再用了,程序还在需要继续运行,继续开辟空间,那岂不是会造成内存泄露? 2.2 free? ? ? ? 不用担心~😶?🌫? ? ? ? ? C语言专门提供了一个函数free,用来解决内存泄漏,回收空间的功能!原型如下:
先来看看free函数的特点吧~
具体应用&&带入刚刚的例子
这里又是一个细节~ p = NULL? ?想象以下,释放了内存,可以不管这个指针p了吗? ? ? ? ? 经过调试可以看到: free前: ?注????????意:p,10可以展示出10个元素,若只是p,只会显示一个值; free后: 和free前有什么一样的,有什么不一样的?? ? ? ? free后,内存还给操作系统,动态开辟的空间里赋的值全部变为随机数,但是,p指针指向的地址依旧没变(x64环境)。 ????????这样会使得指针p十分危险(野指针),即使空间还给了操作系统,但是p地址依旧不变,导致如果以后不小心误用了指针p会导致内存的非法访问! 所以一定要注意,每次释放完动态内存开辟的空间后,请将指针置为NULL; 2.2 calloc????????C语言还提供了一个函数叫 calloc , calloc 函数也用来动态内存分配。
calloc函数有什么特点呢?和malloc函数有什么区别呢?
举个例子: ?可以从内存看出calloc函数开辟好空间,内存就已经全部初始化好成全零了 calloc貌似就等于malloc+memset(初始化全零) 所以如果在需要对开辟好的空间初始化成全零,calloc无疑是个很好的选择! 2.3 realloc? ? ? ? 此函数的出现让动态内存开辟更加灵活!实现了真正意义上的 “动态”~ 🤔写代码时,我们常常会遇到这样一个场景,开辟了一个40个字节的空间,但是后来实际操作中,又感觉不够用了,或者是感觉开辟大了,怎么办呢? ????????那 realloc 函数就可以做到对动态开辟内存大小的调整。 函数原型:
realloc函数的特点?
具体来讲realloc在调整内存空间的是存在两种情况:(如下图解) 例子:在malloc开辟的40个字节的空间扩容到80个字节的空间情况一: ?情况二: 由于上述的两种情况,realloc函数的使用就要注意一些。 举个例子:
观察代码中的思考问题,这样写合理吗? 不合理! ????????想象以下,如果realloc空间开辟失败,就会传给p一个空指针,但是p本身是有指向malloc开辟的那块地址啊,一旦接收空指针,原来的那块空间不就废掉了吗? ????????所以可以考虑用个临时指针来接收,如果realloc开辟成功,再将临时指针赋值给p,就可以有效避免内存泄漏问题 ; 代码实现如下:
3. 常见的动态内存错误对NULL指针的解引用操作直接上代码:
? ? ? ? 想象以下如果malloc开辟失败会发生什么? ? ? ? ? malloc开辟失败返回一个NULL,赋值给ptr ????????造成对NULL指针的解引用操作! 对动态开辟空间的越界访问????????看看以下代码哪里出问题了?
很明显,当赋值10的时候发生了越界访问; 对非动态开辟内存使用free释放
?这样是否可行? ????????ptr一旦++,导致ptr指针不在指向动态开辟的起始位置,这时候free会发生什么呢?(如下图) 这时候有人可能会说:那用const修饰以下不就很安全吗? ????????是啊,安全是安全了,但是ptr = NULL;不也不行了吗?从而产生野指针问题,所以一定要注意避免! ? 使用free释放一块动态开辟内存的一部分
对同一块动态内存多次释放
?动态开辟内存忘记释放(内存泄漏)
注????????意:动态开辟的空间一定要释放,并且正确释放! ? 码字不易~ |
|
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 17:08:13- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |