您好,登录后才能下订单哦!
这篇文章主要讲解了“C++内存管理的知识点有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++内存管理的知识点有哪些”吧!
在C++中,内存可以分为 5 个区,分别为栈,堆,自由存储区,全局/静态变量,常量存储区。
(1)栈:在执行函数时,函数内局部变量的存储单元在栈上创建,函数执行完时这些存储单元被自动释放。
(2)堆:通过 malloc 分配的内存块,通常和 free 搭配,需要手动释放。
(3)自由存储区:通过 new 分配的内存块,通常和 delete 搭配,也需要手动释放。
(4)全局/静态存储区:用于存储全局变量和静态变量。
(5)常量存储区:用于存放常量,不允许修改。
(1)空间分配不同:栈存放函数内的局部变量,由操作系统自动释放;堆通过 malloc 分配,需要手动释放。
(2)缓存方式不同:栈使用的是一级缓存,被调用时处于存储空间;堆使用的是二级缓存,速度要慢些。
(3)数据结构不同:栈类似栈结构,先进后出;堆类似数组结构,先进先出。
malloc 分配在堆中,他会分配一块指定大小的内存空间,并返回一个指针,使用完毕后需要手动回收。
局部变量分配在在栈中,超过作用域后系统自动回收。
(1)数据段:存放程序中已初始化的全局变量和静态变量。
(2)代码段:存放程序执行代码的一块区域,头部包含一些常数变量。
(3)BSS段:存放程序中未初始化的全局变量和静态变量的一块区域。
(4)可执行程序在运行时会多出两个区域:
堆:动态申请内存用。从低向高增长。
栈:存储局部变量,函数参数值。从高向低增长。
(5)在堆和栈之间有个文件映射区。
(1)操作系统创建相应的进程并分配进程空间,加载器把可执行文件中的代码段,数据段映射到进程中的虚拟空间。
(2)加载器读入可执行程序中的导入符号表,根据符号表可以查询需依赖的动态依赖库。
(3)加载器将程序中的动态依赖库进行导入。
(4)初始化应用程序中的全局变量,对于全局变量自动调用构造函数。
(5)进入程序入口函数开始执行。
数据区:存放初始化不为 0 的全局变量和静态变量。
BSS区:存放初始化为 0 或未初始化的全局变量和静态变量。
内存泄漏:
申请了一块儿内存空间,但是使用完毕后没有释放。
(1)new 和 malloc 申请后,没有使用 delete 和 free 释放。
(2)子类继承父类时,父类析构函数不是虚函数。
(3)windows 句柄资源使用后没有释放。
对策:
(1)养成良好的编程习惯,分配的内配使用后,记的释放。
(2)将分配内存的指针以链表的形式存储,使用完毕后从链表中删除进行管理。
(3)使用智能指针。
常见内存错误:
(1)内存分配未成功却使用。
(2)内存分配成功,但是未初始化就引用。
(3)内存分配成功并初始化,但是操作超出了内存的边界。
(4)忘记了释放内存,造成内存泄漏。
(5)释放了内存却继续使用。
对策:
(1)用 malloc 或 new 申请内存后,应该检查返回的指针是否为 NULL。
(2)为指针初始化为 NULL,为数组和动态内存赋初值。
(3)避免数组越界。
(4)动态内存的申请和释放必须配对。
(5)用 free 和 delete 释放内存之后,指针应该置空防止野指针。
(6)使用智能指针。
为了能够使 CPU 进行快速的访问,变量的起始地址应该具有某些特征,即对齐。比如 4 字节的 int,起始地址应该在 4 字节的边界上。
假如变量的地址不是自然对齐,那么 CPU 要访问该值的话需要访问两次或三次内存,而对齐的话只需要一次,访问的速度更快。
内存对齐一般应用在 struct,class,union 数据类型中。
感谢各位的阅读,以上就是“C++内存管理的知识点有哪些”的内容了,经过本文的学习后,相信大家对C++内存管理的知识点有哪些这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。