IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: 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语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-12 23:15:23  更:2021-10-12 23:17:01 
 
开发: 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-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码