C++ 内存主要分为 5 个存储区:
栈(stack): 在执行程序时, 局部变量, 函数参数等存储在该区, 由编译器自动分配和释放. 进栈出栈有相应的计算机指令, 栈内存分配运算内置于处理器的指令集中, 而且分配专门的寄存器存储栈的地址, 效率分高, 内存空间连续, 但栈的内存空间有限.
堆 (heap) 需要程序员手动分配和释放(new 和 delete), 属于动态分配方式, 内存空间充足, 几乎没有限制, 内存空间不连续, 因此会产生内存碎片. 操作系统有一个记录空间内存的链表, 当收到内存申请是便利链表, 找到第一个空间大于申请空间的节点, 将节点 分配给程序, 并将节点从链表中删除.
自由储存区: 与堆十分相似, 分配和释放(malloc,free).
全局 / 静态存储区: 全局变量, 静态变量分配到该区, 直到程序结束时自动释放. 储存区包括 DATA 段 (全局初始化区) 与 BBS 段(全局未初始化区). 其中初始化的全局变量和静态变量被存放在 DATA 段. 未初始化的全局变量和静态变量存放在 BBS 段. 在程序执行前 BBS 段自动清零, 所以为初始化的全局变量和静态变量在程序执行前已经成为 0.
常量存储区: 里面存放常量, 不允许修改. 程序结束后由系统释放
再增加一个程序代码区: 存放程序二进制代码.
堆和栈的区别:
1. 内存管理方式: 栈属于自动存储区, 有编译器自动分配和释放, 而堆需要程序员手动分配和释放(new 和 delete), 容易产生内存泄漏.
2. 空间大小: 栈内存空间是连续的, 空间大小通常是系统预先规定好的, 即栈顶地址和最大空间是确定的. 而堆的内存空间不是连续的, 有一个记录空间的链表负责管理, 因此内存空间几乎没有限制.
3. 是否会产生碎片: 由于栈的内存空间是连续的, 先进后出的方式保证不会产生零碎的空间. 而堆分配方式是每次在空闲的链表中遍历到第一个大于申请空间的节点, 每次分配的空间大小一般不会正好等于申请的内存空间大小, 频繁的 new 操作势必会产生大量的空间碎片.
4. 生长方向: 栈是向着内存地址减小的方向生长, 这也是为什么栈的内存空间有限的原因. 而堆向着内存地址增大的方向生长.
5. 分配方式: 栈有静态分配和动态分配, 而堆只有动态分配. 栈的动态分配与堆不同, 栈的动态分配由编译器释放, 无需手工实现.
6. 分配效率: 栈属于机器系统提供的数据结构, 计算机会在底层对栈提供支持, 出栈进栈都由专门的指令来完成, 因此效率很高. 而堆是 C/C++ 函数库提供的, 当申请空间时需要按照一定算法来搜索足够大小的空间, 当没有足够的空间, 还需要额外处理, 因此效率较低.
内存的静态分配与动态分配:
1. 时间不同: 静态分配发生在程序编译和链接的时候. 动态分配则发生在程序调用和执行的时候.
2. 空间不同: 堆只有动态分配. 栈两者都具备.
使用内存的注意事项:
1. 用 new 和 malloc 申请内存时, 在使用前要检查内存是否分配成功
if(XX == NULL) return ;
2. 使用内存前要进行初始化.
3. 堆内存进行操作时, 防止越界 , 如数组下标范围.
4. 动态分配的内存, 在使用后一定要手动释放, 否则会造成内存泄露.
5. 防止在内存释放之后继续使用它.
变量的生命周期:
变量由编译程序在编译时给其分配存储空间(静态存储分配), 并在程序执行过程中始终存在, 这类变量的生命周期与程序的运行周期相同. 当程序运行时, 该变量的生命周期随即存在, 程序运行结束, 该变量的生命周期随即终止.
变量在程序运行时自动给其分配存储空间(自动存储分配), 这类变量为函数中定义的自动变量. 它们在程序执行到该函数时被创建, 在函数执行结束释放所占用的空间.
来源: http://www.bubuko.com/infodetail-3135873.html