I - 内存分配概述1.1 - 定义概述内存分配 (Memory Allocation) 是指为计算机程序或服务分配物理内存空间或虚拟内存空间的一个过程。通常在程序执行前或执行时完成内存分配。1.2 - 分类概述存在两种类型的内存分配编译时内存分配或静态内存分配 (Compile-time or Static Memory Allocation)运行时内存分配或动态内存分配 (Run-time or Dynamic Memory Allocation)静态内存分配静态内存分配是由编译器为声明的变量分配内存。内存的地址可以通过地址操作符找到并且可以赋值给指针变量。该内存是在编译时分配的。动态内存分配 在程序执行时 (execution) 或 运行时 (run-time) 进行的内存分配被称为动态内存分配。库函数例如 calloc() 和 malloc() 或者操作符 new 均支持分配动态内存。动态分配的内存空间通过这些函数或操作符的返回值分配赋值给指针变量。1.3 - 区别概述序号静态内存分配动态内存分配1在静态内存分配中变量被永久地分配内存直到程序执行结束/函数调用结束在动态内存分配中只有当你的程序单元被激活时才会为变量分配内存2静态内存分配在程序执行前完成动态内存分配在程序执行过程中完成3使用栈来管理静态分配的内存使用堆来管理动态分配的内存4较不高效 (less efficient)较高效5在静态内存分配中不存在内存的重用在动态内存分配中存在内存的重用而且在不需要时可以内存可以被释放6在静态内存分配中一旦内存被分配内存大小就不能再改变在动态内存分配中分配了内存后内存的大小可以改变7在静态内存分配方案中我们不能重新使用未使用的内存动态内存分配中允许重复使用内存。用户可以在需要时分配更多的内存。同时用户也可以在需要时释放内存。8在这种内存分配方案中执行速度比动态内存分配要快在这种内存分配方案中执行速度要比静态内存分配慢9编译时内存分配运行时内存分配10静态分配的内存从程序开始保持到程序结束动态分配的内存可以在任意时刻释放11静态的内存分配常常用于数组等动态的内存分配常常用于链表等数据结构II - 静态内存分配内存必须被分配给我们所创建的变量这样实际的变量才能存在。现在有一个问题即我们认为它是如何运行的以及它实际上是如何运行的计算机如何创建一个变量当我们思考如何创造某样东西时我们会想到“从零开始”着手干而当计算机创建一个变量 ‘X’ 时实际上情况并不是这样对于计算机而言更像是一种分配计算机只是从许多预先存在的内存单元中分配一个内存单元给 X。那么什么是静态内存分配当我们声明变量时我们实际上是在准备所有会被使用的变量这样编译器就知道被使用的变量实际上是用户想要的程序的重要部分而不是到处漂浮的流氓符号。因此当我们声明变量时编译器实际做的是将这些变量分配到它们的房间一个内存单元。现在可以看出这是在程序执行前完成的你不能在程序执行时用这种方法分配变量。示例12345678910voidfunc(){inta;}intmain(){intb;intc[12];//...}上述代码中所有的变量都是静态分配的。III - 动态内存分配那么既然已经存在一种方式来完成内存分配的工作为什么我们需要引入另一种分配方法为什么我们需要在程序执行过程中分配内存因为尽管不是很显而易见但不能在运行时分配内存就降低了灵活性并与空间效率相妥协。特别是在那些事先不知道输入的情况下我们会在存储的低效使用和缺乏或过多的空间用来输入数据方面受到影响给定一个固定长度的数组或类似的数据结构来存储数据。所以引入动态内存分配 在运行时存储/内存/单元可以分配给变量的机制被称为动态内存分配不要与 DMA 相混淆。因此我们可以知道在运行期间分配内存这使我们能够使用我们想要的存储而不用担心任何浪费或者不足。为什么要使用动态分配的原因当我们事先不知道程序需要多少内存的时当我们希望数据结构没有固定的内存空间上限时当你想更有效地使用你的内存空间时。例如 如果你为一个一维数组分配的内存空间是array[20]而你最终只使用了 10 个内存空间那么剩下的 10 个内存空间就被浪费了这些浪费的内存甚至不能被其他程序变量所使用动态创建的列表的插入和删除可以非常容易地通过操作地址来完成而在静态分配的内存中插入和删除会导致更多的移动和内存浪费当你想在编程中使用结构和链表的概念时动态内存分配是必须的C 代码123456789intmain(intargc,char* argv[]){// 动态内存分配int* ptr newint;int* ptr1 newint[10];// 动态分配内存的释放deleteptr;delete[] ptr1;}C 代码1ptr calloc(m, n);等价于12ptr malloc(m * n);memset(ptr, 0, m * n);IV - 小结有两种类型的可用内存 – 栈 (stack) 和堆 (heap)。静态内存分配只能在栈上进行而动态内存分配可以在栈和堆上进行。在堆上进行动态分配的一个例子是递归在递归中函数按照出现的顺序被放入调用堆并在到达基数时一个一个地弹出。当在堆上分配内存时我们需要手动删除内存因为即使分配的内存范围结束如栈的情况内存也不会被编译器自己释放取消分配 deallocate。4.1 - 静态分配的优缺点优点使用简单分配和取消分配都由编译器完成高效的执行时间它使用栈数据结构缺点内存浪费问题必须知道确切的内存需求一旦初始化后内存的大小不能调整4.2 - 动态分配的优缺点优点动态分配是在运行时进行的只要我们需要我们就可以分配创建额外的存储只要我们使用结束了内存就可以被取消分配free / delete动态空间因此人们总是可以准确地拥有所需的空间量–不多也不少。如果需要内存大小可以重新分配缺点由于内存是在运行时分配的因此需要更多的时间。当完成后内存需要由用户释放。这一点很重要因为它更有可能变成难以发现的 bug。总上所述静态内存是编译器提前分配的东西。而动态内存是在执行过程中由程序控制的东西。程序可以要求更多的内存也可以删除部分分配的内存。