1.概念
与数据结构中的栈、堆概念不同。
堆:程序执行过程中的堆是可以动态地扩展和搜索的内存空间,不是连续的内存空间。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。当程序调用malloc、new、free之类的库函数时,堆的大小会变化。
栈:与堆不同,栈的地址是从大到小的连续内存空间,栈顶在底地址端。栈中存放程序中的实参和局部变量,注意全局变量和静态变量是不入栈的,分配与回收全部由操作系统执行。
下图是一个进程的虚拟地址空间分配情况:
1.内核虚拟内存:
内核总是驻留在内存的,是操作系统的一部分。地址空间顶部的区域是为内核保留的,不允许应用进程读写这个区域。
2.栈区:用户栈,编译器用它来实现函数调用。发送函数调用时栈会向下延伸,函数返回时,栈会向上收缩。
3.共享库的内存映像:用来存放C标准库和数学库这样的共享库的代码和数据。
4.堆:由程序分配和回收的运行时内存空间,如malloc,free,new。
5.可读写区域:用于存放全局变量和静态变量
6.只读区:存放程序代码段和常量。
示例代码:
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); //堆
}
2.程序执行过程中的栈情况
C语言代码:
int
fun(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
return *x + *y;
}
int
main(void)
{
int a = 5;
int b = 9;
int c = 3;
c = fun(&a, &b);
a = 7;
b = 17;
return 0;
}
对应的汇编代码: