| |
|
开发:
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++知识库]动态内存管理 |
? ? ? ? ? ? ? ?我们都知道平常的局部变量和函数形式参数实在栈区开辟的,但这个时候其内存所开辟空间的大小是固定的,而且所需要的内存在编译时分配,但很多时候我们所需要的空间大小在程序运行的时候才能知道,这个时候我们就只能试试动态内存开辟了。 目录 1.动态内存函数的介绍1.1 malloc和free
malloc函数的使用方法 这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。 如果开辟成功,则返回一个指向开辟好空间的指针。 如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。 返回值的类型是void*,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。 如果参数size为0,malloc的行为是标准是未定义的,取决于编译器。 C语言提供了另外一个函数free,专门是用来做动态内存的释放和回收
1.2 calloc函数
函数的功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0。与函 数malloc的区别只在于calloc会在返回地址之前把申请的空间的每个字节初始化为全0。
1.3? realloc函数? ? ? ?realloc函数的出现让动态内存管理更加灵活。有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时候内存,我们一定会对内存的大小做灵活的调整。那realloc函数就可以做到对动态开辟内存大小的调整。
ptr是要调整的内存地址 size 调整之后新大小 返回值为调整之后的内存起始位置。 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
realloc在调整内存空间的是存在两种情况: 第一种:原有空间之后有足够大的空间,此时要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。 第二种:原有空间之后没有足够大的空间,在堆空间上另找一个合适大小的连续空间来使用。这样函数返回的是一个新的内存地址。 2.常见的动态内存错误2.1对NULL指针的解引用操作
2.2 对动态开辟空间的越界访问
2.3 对非动态开辟内存使用free释放
此时free函数的行为是未定义的 2.4 使用free释放一块动态开辟内存的一部分
此时p指针指向空间最后的地址,因此free函数不能完全释放 2.5 对同一块动态内存多次释放
2.6 动态开辟内存忘记释放(内存泄漏)
3.动态内存经典笔试题题1:
此时的程序运行会有什么问题呢? ? ? ? ?首先我们建立一个char*类型的空指针,然后我们调用GetMemory函数,str是值传递,用p来接收,因此p是str的一份临时拷贝,所以当malloc开辟的空间起始地址放在p中的时候,不会影响str,str仍然是NULL指针。当str是空指针的时候,strcpy是不能直接将字符串直接拷贝到str空间的,因为NULL指向的空间是不能直接被访问的,因此程序会崩溃。 既然如此,我们应该如何改正呢? 下面我们看正确代码: 方法1:传址操作
方法2:强行带回p
题2:
?此题打印的是随机值: ? ? ? ?主要是因为我们调用GetMemory函数的时候,在里面创建了字符数组,再带回来时,创建的数组已经销毁,因此str打印出来的是随机值。创建数组的时候前面加static静态变量就可以。 题3:
此题是传址操作,前面都没问题,可是strcpy将字符串复制之后,并没有释放malloc开辟的空间,因此会造成内存泄漏。后面加上free(str);str=NULL;即正确。 题4:
此处char* str接收malloc开辟的空间,后面使用完之后,并没有将str置为空指针,就直接判断str是否为空,此时这里的str是个野指针,因此free(str)之后str=NULL,则正确 4.C/C++程序的内存开辟? ?C/C++程序内存分配的几个区域: 1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。 2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表。 3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。 4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码。 5.柔性数组5.1柔性数组概念C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员。 ?
5.2柔性数组的特点结构中的柔性数组成员前面必须至少一个其他成员。 sizeof 返回的这种结构大小不包括柔性数组的内存。 包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。 即柔性数组一般与动态开辟内存配合使用: 举例:
5.3柔性数组的优势上个柔性数组也有另一种使用方式:
但此处free释放malloc开辟的空间要释放两次,柔性数组只需要释放一次。 使用柔性数组好处1:方便内存释放 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?2:连续的内存有益于提高访问速度,也有益于减少内存碎片。 |
|
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/24 0:42:38- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |