一.概述
一个由C/C++编译的程序占用的内存分为以下几个部分 :堆区、栈区、全局区(静态区)、文字常量区、代码区五部分。
在执行一个C/C++语言程序时,此程序将拥有唯一的“内存四区”——栈区、堆区、全局区、代码区。每个程序都有唯一的四个内存区域。
1、一个可执行程序在存储(没有调入内存)时分为代码段、静态区和文字常量区三部分;
2、可执行程序(调入内存后)在运行时又多出两个区域:栈区和堆区。
1、堆区(heap) — 允许程序在运行时动态地申请某个大小的内存空间, 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事。
2、栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。
3、全局区(静态区)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,程序结束后由系统释放。
4、文字常量区 —常量字符串就是放在这里的,只读的。程序结束后由系统释放。
5、程序代码区—存放程序的编译后的可执行二进制代码,CPU执行的机器指令,并且是只读的。
int a = 0; 存放在全局初始化区
char *p1; 存放在全局未初始化区
main()
{
int b; 栈区
char s[] = "abc"; 栈区
char *p2; 栈区
char *p3 = "123456"; 123456\0在常量区,p3在栈区。
static int c =0; 全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的
"123456"优化成一个地方。
}
二.内存分布图
三.堆和栈的对比
四. 数据结构中的堆,栈和内存分配中的堆,栈的区别
下面说一下C语言程序内存分配中的堆和栈,这里有必要把内存分配也提一下,大家不要嫌弃本姑娘萝莉啰嗦啦,一般情况下 程序存放在Rom或Flash中,运行事需要拷贝到内存中执行,内存会分别存储不同的信息。
1、数据结构中的堆
堆的定义:是一棵完全二叉树结构,特点是父节点的值大于(小于)两个子节点的值(分别称为大顶堆和小顶堆)。堆是一种经过排序的树形数据结构,每个结点都有一个值。通常我们所说的堆的数据结构,是指二叉堆。它常用于管理算法执行过程中的信息,应用场景包括堆排序,优先队列等。
堆的特点:是根结点的值最小(或最大),且根结点的两个子树也是一个堆。由于堆的这个特性,常用来实现优先队列,堆的存取是随意,
堆的形象例子:就如同我们在图书馆的书架上取书,虽然书的摆放是有顺序的,但是我们想取任意一本时不必像栈一样,先取出前面所有的书,书架这种机制不同于箱子,我们可以直接取出我们想要的书。
2、内存分配中的堆
堆的定义:堆允许程序在运行时动态地申请某个大小的内存空间,从堆中分配的内存需要程序员手动释放,如果不释放,而系统内存管理器又不自动回收这些堆内存的话,那就一直被占用(Java中由JVM虚拟机的垃圾回收机制自动回收)。如果一直申请堆内存,而不释放,内存会越来越少。
3.数据结构中的栈
栈:像是装数据的桶或者箱子
栈是大家比较熟悉的一种数据结构,它是一种具有后进先出的数据结构,也就是说后存放的先取,先存放的后取,这就类似于我们要在取放在箱子底部的东西(放进去比较早的物体),我们首先要移开压在它上面的物体(放入比较晚的物体)。
4.内存中的栈
内存中的栈区处于相对较高的地址,以地址的增长方向为上的话,栈地址是向下增长的。
栈中分配局部变量空间,堆区是向上增长的用于分配程序员申请的内存空间。另外还有静态区是分配静态变量,全局变量空间的。只读区是分配常量和程序代码空间的;以及其他一些分区。