C语言和堆栈的联系:

栈 Stack:

必须要先给C语言分配一个可用的栈空间,C语言才能运行,因为C语言里的临时变量都是放在空间里的,没有栈C语言是无法运行的。

堆 Heap:

堆空间就是我们申请的内存空间,用malloc函数申请的。C语言中当想要使用内存时就可以向堆区申请,但是使用时要注意及时释放不用的内存,以免造成内存泄漏。

堆和栈的理解:完全不同的两个概念

栈:栈是一种数据结构(先进先出),栈空间由系统管理,不需要申请和释放,C语言里的临时变量会自动放到栈里,压栈和弹栈都不需要程序员操心。
堆:堆是一种特殊的完全二叉树的数据结构,简单来说就是管理系统里空闲的内存,可以通过malloc申请和free释放,需要程序员手动操作。

栈的分类:

  1. 满减栈:进栈(先移动指针再入栈,指针往地址减小的方向移动);出栈(先出栈,栈指针往地址 增大的地方移动)。
  2. 满增栈:进栈(先移动指针再入栈,指针往地址增大的方向移动);出 栈(先出栈,栈指针往地址减小的地方移动)。
  3. 空减栈:进栈(先进栈,栈指针往地址减小的方向移动);出栈(先移动指针再出栈,栈指针往地址增大的方向移动)
  4. 空增栈:进栈(先进栈,栈指针往地址增大的方向移动);出栈(先移动指针再出栈,栈指针往地址减小的方向移动)

备注:使用时不用纠结时哪一种栈结构,只要进栈和出栈用同一种栈结构就不会出错。

栈的特性:

1.栈空间一般是由编译器指定大小和在内存中的位置,并且栈的空间一般不大,如果在程序中要定义字节数较多的变量,尽量申请堆空间,不然会栈溢出,造成程序崩溃。
2.C语言运行时必须要分配栈空间,但是我们在写C语言程序时并没有初始化栈的相关操作,这是因为编译器自动给我们分配了栈空间,再生成可执行程序时,会自动把初始化栈的代码给链接进去。并且因为采用虚拟地址的原因,每个进程都认为自己独占整个内存,所以编译器分配栈空间时也是比较方便的。
3.栈空间是不用C程序员去管理的,进栈和出栈都是自动的,C程序员只需要保证栈不溢出就行。
4.栈是脏的。也就是定义一个临时变量分配得到的栈空间,栈空间的内容是随机的,没有被初始化过,这也是为什么我们写代码时,定义临时变量时最好初始化一个值(一般是0),不然变量的值就是乱码。背后的原因是,我们使用完栈空间后,不会去清空栈空间,当回收回去的栈空间下一次分配出去时,还保留着上一次的数据,所以定义的临时变量值是随机的。

堆的特性:

1.堆空间:内存中,除了已经分配为栈空间或者其他用途的空间,剩余还没用的空间都可以叫做堆空间
拓展:在海思芯片里内存分为系统内存和mmz内存,系统内存由操作系统管理,mmz由海思底层进行管理。其中用malloc申请的是系统内存,用海思提供的接口申请的是mmz内存。
2.堆空间的申请(malloc)和释放(free)都是程序员手动操作的,尤其要注意及时释放不需要的内存,否则会造成内存泄漏,程序崩溃。

堆的使用:

1.堆空间的申请要避免频繁、少字节数的申请,因为频繁多次申请会造成内存碎片,不利于内存管理。如果是要频繁使用的内存空间,可以在初始化的时候就申请好,并用一个静态变量记录下申请的内存地址,后面就可以反复利用而不用频繁的申请释放。
2.如果不可避免的要频繁、少字节的使用内存,可以再初始化的时候,一次性申请一大块内存,然后需要的时候从之前申请的一大块内存中分配出去一块。其中就要求程序员要自己设计出一套管理这块内存的逻辑,一般情况下使用链表就足以,使用内核链表会更方便。


引用:
作者:正在起飞的蜗牛
来源:https://blog.csdn.net/weixin_42031299/article/details/115422473