- 静态存储区(全局存储区)
- 堆区
- 栈区
- 代码区
- 文字常量区
内存分区图:程序员
app启动后,代码区,文字常量区,全局存储区大小固定,指向这些区的指针不会产生崩溃性的错误。而堆区和栈区是时时刻刻变化的(堆的建立销毁,栈的弹入弹出),当使用一个指针指向这两个区的内存时,要注意内存是否已释放,指向已经释放的内存会产生野指针。数据结构
内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。app
全局变量、静态变量会存储在此区域。事实上全局变量也是静态的,所以,也叫全局静态存储区。函数
存储方式:操作系统
- 初始化的全局变量跟静态变量放在一片区域(数据区)
- 未初始化的全局变量与静态变量放在相邻的另外一片区域(BSS区)
程序结束后由系统释放。指针
在程序中使用的常量存储在此区域(常量字符串就是放在这里的)。程序结束后,由系统释放。在程序中使用的常量,都会到文字常量区获取。cdn
存放函数体的二进制代码,运行程序就是执行代码,代码要执行就要加载进内存。对象
亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员本身负责在适当的时候用free或delete释放内存。动态内存的生存期能够由咱们决定,若是咱们不释放内存,程序将在最后才释放掉动态内存(若是某动态内存再也不使用,须要将其释放掉,不然认为发生了内存泄漏现象)。blog
动态分配和回收,不能静态分配(堆区的地址是从低到高分配)。内存
分配步骤:
- 操做系统有一个记录空闲内存地址的链表
- 当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,而后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序
- 因为找到的堆结点的大小不必定正好等于申请的大小,系统会自动的将多余的那部分从新放入空闲链表中
大小限制:
堆是向高地址扩展的数据结构,的内存区域因为系统是用链表来存储的空闲内存地址的,是不连续,而链表的遍历方向是由低地址向高地址。堆的大小受限于系统中有效的虚拟内存。因而可知,堆得到的空间比较灵活,也比较大。
在堆中咱们不是按照进入堆的前后顺序来提取元素,而是根据元素的优先级来提取元素,整体来讲,堆是一种数据结构,它的插入和删除的操做,要根据优先级来决定,同时堆也有以下几个特性:
- 任意节点的优先级不小于它的子节点
- 任意节点的值都小于或者等于它的子节点
- 主要操做是插入和删除它的最小元素(元素值自己就是优先级的键值,小元素享有高优先级) (每次取出优先级最高的元素,便是让堆的最上层参与者退出堆)
由上面可看出堆的优势是灵活方便,数据适应面普遍,可是效率有必定下降。[顺序随意]
在执行函数时,函数内局部变量的存储单元均可以在栈上建立,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,可是分配的内存容量有限。存储的为非静态的局部变量,例如:函数参数,在函数中生命的对象的指针等。当系统的栈区大小不够分配时, 系统会提示栈溢出。
分配方式:(栈区地址从高到低分配),静态分配(例如:局部变量的分配)和动态分配(例如,alloc函数进行分配)都由系统完成,不须要手动管理
分配步骤:
- 存储每个函数在执行的时候都会向操做系统索要资源,栈区就是函数运行时的内存。
- 栈区中的变量由编译器负责分配和释放,内存随着函数的运行分配,随着函数的结束而释放,由系统自动完成。
大小限制:
栈是向低地址扩展的数据结构,是一块连续的内存的区域。是栈顶的地址和栈的最大容量是系统预先规定好的 ,若是申请的空间超过栈的剩余空间时,将提示内存溢出。所以,能从栈得到的空间较小。
只容许在连接串列或者阵列的一段(通常为栈顶)进行加入数据(push)或者输出数据(pop)。因为栈只容许在一端进行操做,按照先进后出的原则来进行。 优势是快速高效,缺点时有限制,数据不灵活。[先进后出]
栈的三个操做:
- Pop:取出栈中最上层的元素
- top:查看栈顶元素
- push:将一个新的元素放在栈的最上层。