C语言学习(六):内存分配

1.存储器

常用的存储器类型如下:
C语言学习(六):内存分配_第1张图片

2. 内存分配

参考链接

2.1 内存分配机制
1)栈(Stack):位于函数内的局部变量(包括函数实参),由编译器负责分配释放,函数结束,栈变量失效。
(2)堆(Heap):由程序员用malloc/calloc/realloc分配,free释放。如果程序员忘记free了,则会造成内存泄露,程序结束时该片内存会由OS回收,但程序只要不结束,就有可能造成内存泄露。(程序员负责分配和释放)
(3)全局区/静态区(Global Static Area): 全局变量和静态变量存放区,程序一经编译好,该区域便存在。并且在C语言中初始化的全局变量和静态变量和未初始化的放在相邻的两个区域(在C++中,由于全局变量和静态变量编译器会给这些变量自动初始化赋值,所以没有区分了)。由于全局变量一直占据内存空间且不易维护,推荐少用。程序结束时释放。
(4)C风格字符串常量存储区: 专门存放字符串常量的地方,程序结束时释放。
(5)程序代码区:存放程序二进制代码的区域。
2.2 堆和栈

堆(Heap)

  • 由程序员用malloc/calloc/realloc分配,free释放。如果程序员忘记free了,则会造成内存泄露,程序结束时该片内存会由OS回收,但程序只要不结束,就有可能造成内存泄露。(程序员负责分配和释放)

栈(Stack)

  • 位于函数内的局部变量(包括函数实参),由编译器负责分配释放,函数结束,栈变量失效
2.3 堆栈区别

从以上介绍中,它们有如下区别:

  1. 栈是系统提供的功能,特点是快速高效,缺点是由限制,数据不灵活;而堆是函数库提供的功能,特点是灵活方便,数据适应面广,但是效率有一定降低。
  2. 栈是系统数据结构,对于进程/线程是唯一的;堆是函数库内部数据结构,不一定唯一。不同堆分配的内存无法互相操作。
  3. 栈空间分静态分配和动态分配,一般由编译器完成静态分配,自动释放,栈的动态分配是不被鼓励的;堆的分配总是动态的,虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存/释放内存匹配是良好程序的基本要素。
  4. 碎片问题:对于堆来讲,频繁的new/delete等操作势必会造成内存空间的不连续,从而造成大量的碎片,使程序的效率降低;对于栈来讲,则不会存在这个问题,因为栈是后进先出(LIFO)的队列。
  5. 生长方向:堆的生长方向是向上的,也就是向这内存地址增加的方向;对于栈来讲,生长方向却是向下的,是向着内存地址减少的方向增长。
  6. 分配方式:堆都是动态分配的,没有静态分配的堆;栈有两种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配则由alloca函数进行分配,但是栈的动态分配和堆不同,它的动态分配是由编译器进行释放,无需我们手工实现。
  7. 分配效率:栈是机器系统提供的数据结构,计算机在底层提供支持,分配有专门的堆栈段寄存器,入栈出栈有专门的机器指令,这些都决定了栈的高效率执行。而堆是由C/C++函数库提供的,机制比较复杂,有不同的分配算法,易产生内存碎片,需要对内存进行各种管理,效率比栈要低很多。

你可能感兴趣的:(C,and,C++)