一、内存在计算机中每个应用程序之间的内存是相互独立的通常情况下应用程序 A 并不能访问应用程序 B当然一些特殊技巧可以访问但此文并不详细进行说明。例如在计算机中一个视频播放程序与一个浏览器程序它们的内存并不能访问每个程序所拥有的内存是分区进行管理的。在计算机系统中运行程序 A 将会在内存中开辟程序 A 的内存区域 1运行程序 B 将会在内存中开辟程序 B 的内存区域 2内存区域 1 与内存区域 2 之间逻辑分隔。1.1 内存四区在程序 A 开辟的内存区域 1 会被分为几个区域这就是内存四区内存四区分为栈区、堆区、数据区与代码区。栈区指的是存储一些临时变量的区域临时变量包括了局部变量、返回值、参数、返回地址等当这些变量超出了当前作用域时将会自动弹出。该栈的最大存储是有大小的该值固定超过该大小将会造成栈溢出。堆区指的是一个比较大的内存空间主要用于对动态内存的分配在程序开发中一般是开发人员进行分配与释放若在程序结束时都未释放系统将会自动进行回收。数据区指的是主要存放全局变量、常量和静态变量的区域数据区又可以进行划分分为全局区与静态区。全局变量与静态变量将会存放至该区域。代码区就比较好理解了主要是存储可执行代码该区域的属性是只读的。1.2 使用代码证实内存四区的底层结构由于栈区与堆区的底层结构比较直观的表现在此使用代码只演示这两个概念。首先查看代码观察栈区的内存地址分配情况12345678#includestdio.hintmain(){inta 0;intb 0;charc0;printf(变量a的地址是%d\n变量b的地址是%d\n变量c的地址是%d\n, a, b, c);}运行结果为我们可以观察到变量 a 的地址是 2293324 变量 b 的地址是 2293320由于 int 的数据大小为 4 所以两者之间间隔为 4再查看变量 c我们发现变量 c 的地址为 2293319与变量 b 的地址 2293324 间隔 1因为 c 的数据类型为 char类型大小为 1。在此我们观察发现明明我创建变量的时候顺序是 a 到 b 再到 c为什么它们之间的地址不是增加而是减少呢那是因为栈区的一种数据存储结构为先进后出如图首先栈的顶部为地址的“最小”索引随后往下依次增大但是由于堆栈的特殊存储结构我们将变量 a 先进行存储那么它的一个索引地址将会是最大的随后依次减少第二次存储的值是 b该值的地址索引比 a 小由于 int 的数据大小为 4所以在 a 地址为 2293324 的基础上往上减少 4 为 2293320在存储 c 的时候为 char大小为 1则地址为 2293319。由于 a、b、c 三个变量同属于一个栈内所以它们地址的索引是连续性的那如果我创建一个静态变量将会如何在以上内容中说明了静态变量存储在静态区内我们现在就来证实一下12345678910#includestdio.hintmain(){inta 0;intb 0;charc0;staticintd 0;printf(变量a的地址是%d\n变量b的地址是%d\n变量c的地址是%d\n, a, b, c);printf(静态变量d的地址是%d\n, d);}运行结果如下以上代码中创建了一个变量 d变量 d 为静态变量运行代码后从结果上得知静态变量 d 的地址与一般变量 a、b、c 的地址并不存在连续他们两个的内存地址是分开的。那接下来在此建一个全局变量通过上述内容得知全局变量与静态变量都应该存储在静态区代码如下123456789101112#includestdio.hinte 0;intmain(){inta 0;intb 0;charc0;staticintd 0;printf(变量a的地址是%d\n变量b的地址是%d\n变量c的地址是%d\n, a, b, c);printf(静态变量d的地址是%d\n, d);printf(全局变量e的地址是%d\n, e);}运行结果如下从以上运行结果中证实了上述内容的真实性并且也得到了一个知识点栈区、数据区都是使用栈结构对数据进行存储。在以上内容中还说明了一点栈的特性就是容量具有固定大小超过最大容量将会造成栈溢出。查看如下代码123456#includestdio.hintmain(){chararr_char[1024*1000000];arr_char[0] 0;}以上代码定义了一个字符数组 arr_char并且设置了大小为 1024*1000000设置该数据是方便查看大小随后在数组头部进行赋值。运行结果如下这是程序运行出错原因是造成了栈的溢出。在平常开发中若需要大容量的内存需要使用堆。堆并没有栈一样的结构也没有栈一样的先进后出。需要人为的对内存进行分配使用。代码如下123456789#includestdio.h#includestring.h#include malloc.hintmain(){char*p1 (char*)malloc(1024*1000000);strcpy(p1,这里是堆区);printf(%s\n, p1);}以上代码中使用了strcpy 往手动开辟的内存空间 p1 中传数据“这里是堆区”手动开辟空间使用 malloc传入申请开辟的空间大小 1024*1000000在栈中那么大的空间必定会造成栈溢出而堆本身就是大容量则不会出现该情况。随后输出开辟的内存中内容运行结果如下在此要注意p1是表示开辟的内存空间地址。二、malloc 和 free在 C 语言不是 C)中malloc 和 free 是系统提供的函数成对使用用于从堆中分配和释放内存。malloc 的全称是 memory allocation 译为“动态内存分配”。2.1 malloc 和 free 的使用在开辟堆空间时我们使用的函数为 mallocmalloc 在 C 语言中是用于申请内存空间malloc 函数的原型如下1void*malloc(size_tsize);在 malloc 函数中size 是表示需要申请的内存空间大小申请成功将会返回该内存空间的地址申请失败则会返回 NULL并且申请成功也不会自动进行初始化。细心的同学可能会发现该函数的返回值说明为 void *在这里 void * 并不指代某一种特定的类型而是说明该类型不确定通过接收的指针变量从而进行类型的转换。在分配内存时需要注意即时在程序关闭时系统会自动回收该手动申请的内存 但也要进行手动的释放保证内存能够在不需要时返回至堆空间使内存能够合理的分配使用。