程序运行时,涉及操作的内存的类别有:
栈区(stack) : 由编译器自动分配释放,存放函数的参数值,局部变量的值。
堆区(heap) : 一般由程序员分配和释放,若程序员不释放,程序结束后由系统回收。
全局区,也叫静态区(static) : 存储全局变量和静态变量,初始化的在一块区域,未初始化的在另一块,程序结束后由系统回收。
文字常量区,也叫数据段:常量字符串就是放在这里,程序结束后系统回收。
程序代码区,也叫代码段:存放程序的二进制代码。
堆和栈:
- 申请方式
栈是系统自动分配的,堆需要程序员自己申请,并指明大小。 - 申请后系统的响应
栈的话,只要栈的剩余空间大于申请空间,则分配内存,否则将报异常提示栈溢出。
堆的话,系统将遍历记录空闲内存地址的链表,找到第一个空间大于申请空间的内存块分配给程序,并在内存块的首地址记录本次分配的大小,这样delete才能正确释放内存。另外,多余的内存会重新加入空闲内存链表。 - 申请大小限制
栈,在windows中,由于是向低地址生长的,是一块连续的内存区域。并且栈顶的地址和栈的最大容量是系统预先规定好的。在windows中,栈的大小是2MB,因此申请的空间是有限的。
堆,则是向高地址生长的,是不连续的内存区域,大小受限于计算机中的空闲内存块大小。堆获得的空间比较灵活,也比较大。 - 申请效率
栈是系统自动分配,速度较快。
堆的速度较慢,且容易产生内存碎片。 - 存储的内容
栈,函数调用时,首先进栈的是函数的下一条指令,然后是函数的参数,注意参数是从右向左进栈,然后是函数的局部变量,函数中的静态变量不进栈。
堆,首先在堆的头部存放堆的大小。然后由程序员决定其中的内容。 - 存取效率
char s1[]="aaaa";
char *s2="aaaa";
第一行是在运行时赋值,即先定义一个数组s1然后为数组赋值,"aaaa"存放于栈中;第二行则是在编译时赋值,"aaaa"存放于文字常量区。
栈的存取速率比堆快,所以之后s1的存取比s2快。