C/C++ 程序内存的分配

  1. 内存划分

  2. 三种内存分配方式

  3. 内存分配简易图

  4. 堆和栈的区别

  5. 动态内存管理

  6. 全局变量、局部变量的区别

一、内存划分

栈区(stack) :由编译器自动分配与释放,存放为运行时函数分配的局部变量、函数参数、返回数据、返回地址等

堆区(Heap):一般由程序员自动分配,如果程序员没有释放,程序结束时可能由 OS 回收,其分配类似于链表

全局区(静态区 static): 存放全局变量、静态数据、常量。程序结果后由系统释放,全局区分为初始化全局区(data) 与未初始化全局区(bss)

常量区(文字常量区):存放常量字符串,程序结束后由系统释放

代码区:存放函数体(类成员函数和全局区)的二进制代码

二、三种内存分配方式

从静态存储区分配

内存在程序编译的时候已经分配好,这块内存在程序的整个运行期都存在。例如全局变量、static 变量

在栈上创建

在执行函数时,函数内局部变量的存储单元可以在栈上创建,函数执行结束时,这些内存单元会自动被释放。栈内存分配运算内置于处理器的指令集,效率高,但是分配的内存容量有限

从堆上分配

也叫做动态内存分配,程序在运行的时候使用 malloc 或者 new 申请任意多少的内存,程序员自己负责在何是 free 或 delete 释放内存。

动态内存的生命周期由程序员决定,使用非常灵活,但如果在堆上分配了空间,需要有责任回收它,否则运行时的程序会出现内存泄漏,频繁的分配和释放不同大小的堆空间将会产生内存碎片

三、内存分配简易图

 在C中,全局变量又分为初始化的与未初始化的(未初始化的对象存储区可以通过void* 来访问和操作,程序结果后由系统自行释放)

四、堆和栈的区别

  1. 管理方式的不同:栈由编译器自动申请和释放空间,堆是需要程序员手动申请和释放
  2. 空间大小的不同:栈的空间是有限的,在32位平台下,vc6 下默认 1M,堆最大可以到 4G
  3. 能否产生碎片:栈和数据结构中的栈的原理相同,在弹出一个元素之前,上一个已经弹出了,不会产生碎片。如果不停地调用 malloc 、free 会造成内存碎片很多
  4. 生长方式不同:堆生长方式是向上的,也就是向着内存地址增加的方向,栈刚好相反,向着内存减少的方向生长
  5. 分配方式的不同:堆都是动态分配的,没有静态分配的堆。栈有静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配是由malloc 函数进行分配,但是栈的动态分配和堆是不同的,它的动态分配是由编译器进行释放,无需手动实现
  6. 分配效率不同:栈的效率比堆高很多,栈是机器系统提供的数据结构,计算机在底层提供栈的支持,分配专门的寄存器来存放栈的地址,压栈出栈都有相应的指令,因此比较快。堆是由库函数提供的,机制很复杂,库函数会按照一定的算法进行搜索内存,比较慢

五、动态内存管理

六、静态全局变量、局部变量、静态局部变量、局部变量的区别

静态全局变量、全局变量的区别

  1. 静态全局变量和全局变量都属于常量区
  2. 静态全局区只在本文件中有效,别的文件想调用该变量是不行的,而全局变量在别的文件中是可以调用的
  3. 如果别的文件中定义了一个该全局变量相同变量名,是会出错的

静态局部变量、局部变量的区别

  1. 静态局部变量属于常量区,而函数内部的局部变量属于栈区
  2. 静态局部变量在该函数调用结束时不会销毁,而是随着整个程序结束而结束。但是别的函数调用不了该变量,局部变量随该函数的结束而结束
  3. 如果定义这两个变量的时候没有初始值,静态局部变量会自定义位0,而局部变量就是一个随机值
  4. 静态局部变量在编译器只赋值一次,以后每次函数调用时,不再赋值,调用上次的函数调用结束时的值。局部变量在调用期间,美调用一次,赋一次值

 参考:https://blog.csdn.net/cherrydreamsover/article/details/81627855

原文地址:https://www.cnblogs.com/bytecodebuffer/p/13970467.html