| |
|
开发:
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++内存分配管理 |
? 一、内存分配方式 ?1、程序运行前(编译后) ? ? ???代码区? 存放CPU执行的机器指令,即编写的所有代码 ? ? ? ? ? ? ? ? ? ? ?代码区是共享的,其原因是对于频繁被执行的程序,只需要在内存中有一份代码即可 ? ? ? ? ? ? ? ? ? ? ?代码区是只读的,放置程序意外第修改了它的指令 ? ? ? ?全局区(包含常量存储区、静态存储区) ? ? ? ? ? ?(1) 静态存储区:存放静态变量(static)、全局变量 ? ? ? ? ? ?(2)常量存储区:字符串常量、const修饰的全局常量 ? ? 2、程序运行后 ? ? ? ??栈区 由编译器自动分配,存放函数的参数值、局部变量等;函数结束时,系统自动回收。 ? ? ? ? ? ? ? ? ?栈内存分配运算内置于处理器的指令集中,效率很高,但分配的内存空间有限。 ? ? ? ? 堆区? 由程序员分配释放,程序员不释放,程序结束时由操作系统回收。 ? ? ? ? ? ? ? ? C++中主要利用new在堆区开辟内存(该块内存又称为自由存储区) ? ? ? ?堆和栈的区别参考:c++ 内存管理_AITBOOK-CSDN博客 ? 二、C++中可能出现的内存问题及解决办法 ? 1 缓冲区溢出 ? ? ?由程序员自己编写Buffer类来管理缓冲区,自动记住使用缓冲区的大小,通过成员函数(不是裸指针)来修改缓冲区。? ? ? ? ?? ? 2 野指针 ? ???野指针:指针变量指向非法的内存空间,如:使用没有申请的内存,或者已经释放的内存 ? ???解决办法:(1)在使用内存前,检查指针是否为空指针NULL ? ? ? ? ? ? ? ? ? ? ? ?(2)一个指针指向一个对象,当对象销毁时,该指针应该自动置为NULL,而不需要? ? ? ? ? ? ? ? ? ? ? ? 对象通知重置。C++11提供shared_ptr/weak_ptr(下面内存泄漏部分详细阐述)可以解? ? ? ? ? ? ? ? ? ? ? ? ?决,我们在编写程序时,尽量使用智能指针,避免野指针。 ? ?空指针:定义 int *p = NULL 表示指针变量指向内存中编号为0的空间 ? ? ? ? ? ? ? ? ? ? ? ?空指针指向的内存是不可访问的,0~255号内存被系统占用 ? ? ? ? ? NULL本质是宏#define NULL 0,这里的0既可以表示整型常量,又可以表示指针常量。 ? ? ? ? ? 这带 来一些问题,例如:无法区分void fun(int a) 与void func(int* a)。 ? ? ? ? ? C++11 中提供nullptr表示空指针,nullptr是指针类型,不能转换成整型类型,建议使用 ?3 重复释放 ? ? C++中一个指针被重复delete,编译时不会报错,在运行时才报错。 ? ? 浅拷贝:一个类中有属性m_A(指针数据)开辟在堆区,对象P2通过对象P1进行拷贝构造创建,P1和P2的属性的属性指向同一块内存。在函数运行结束后,P1和P2都调用析构函数释放时(释放顺序:先进后出),先释放P2(此时堆区内存已经释放),再释放P1(堆区内存又释放一次) ? ? 可以利用深拷贝来解决浅拷贝带来的问题,我们只需重载拷贝构造函数,通过P1构造P2时,在堆区重新开辟空间,放P2的属性m_A。 ? ?重载拷贝构造时需要注意的问题:形参一般是常量引用,如 const Person &p ? ? ? 设置为常量,防止出错,只读 (拷贝操作,值必然不能改变) ? ? ? 必须设置为引用, 否则传参时,自动调用拷贝构造,拷贝一个临时副本,导致拷贝构造函数无限的递归,最终使栈溢出。 ?4 内存泄漏 ? ? 未能及时释放不再使用的内存(借东西不还,程序功能),失去对内存的控制(并不是物理内存消失),常指堆区内存泄漏,因为堆是动态分配的,由程序员控制的,使用不当就会出现内存泄漏问题。 解决办法:(1)动态内存的申请和释放必须配对,即new-delete 和 malloc-free ? ? ? ? ? ? ? ? ? ?(2)shared_ptr指针 管理动态申请new的对象的销毁。 shared_ptr共享指针原理:若某块内存被多个指针共享,使用计数器表示该对象被几个指针调用。一般通过use_count()函数查看有几个指针;通过release()释放内存,每当一个指针释放,计数减1,当计数减为0时,自动释放该块内存,从而避免内存泄漏。? ? ? ? ?? ?5? 不配对的new和delete ? ? ?一般把new[]换成vector或array开辟连续存储空间 ?6 内存碎片 对于堆来讲,频繁的new/delete会造成内存空间的不连续,产生大量碎片,使程序效率降低。 对于栈来讲,不会存在这个问题,因为栈是先进后出的,压根不会存在某个内存块从栈中间弹出。 解决办法:(1)?内存池技术,相同大小或者大小接近的内存都放到同一个内存池,这样从内存池的? ? ? ? ? ? ? ? ? ? ? ? ?每个内存块之间浪费的内存会非常小或者没有浪费。 ? ? ? ? ? ? ? ? ? ? ? ?优点:一次性先从操作系统OS申请一大块内存,所以,在为每个对象分配内存时? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?候,就不?用再跟OS交互了,能够提升效率。 ? ? ? ? ? ? ? ? ? (2)内存池向系统申请内存时都以页为单位进行申请大块内存,内存池对外分配内存也? ? ? ? ? ? ? ? ? ? ? ? ? 以优先使用使用率最高的内存块,这样会有更高的效率将整个内存块归还系统 ?本文参考C/C++内存分配管理_一只大笨猫的博客-CSDN博客_c++内存分配 ? ? ? ??? ? ? ? C++内存碎片的处理机制_wingnet-CSDN博客 ? ? ? ? ? ? ? ??C++内存管理(面试版)_知愚的博客-CSDN博客? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ??C/C++的内存碎片、内存泄漏以及内存越界问题的解决方案_daphnis的博客-CSDN博客 |
|
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/19 8:28:33- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |