new的动态内存分配在堆(heap)上
程序中定义的局部数据存储在栈上
1.堆是大家共有的空间,分为全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程初始化的时候进行统一分配,运行过程中也可以向系统要额外的堆,但是用完之后要还给操作系统,否则会内存泄露。
2.栈是线程 所独有的,用于保存其运行状态和局部变量。栈在线程开始的时候初始化,每个线程的栈互相独立。每个函数都有自己的栈,栈被用来在函数之间传递参数。操作系统在切换线程的时候会自动地切换栈。
3.栈空间不需要再高级语言中显示地分配和释放,栈是由编译器自动分配释放空间,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。堆一般由程序员分配释放,若不释放,操作系统并不能保证在程序结束的时候对堆进行回收。
4.栈是存放函数的所有动态局部变量及函数调用和返回的有关信息的一块内存。栈的内存管理严格遵循后进先出的顺序。从栈中分配内存的效率比较高。从堆中获取内存比栈中慢的多,但是堆得内存管理比栈灵活很多,任何时候都可以从堆中获得内存。
eg.
void Function(void)
{
char *p = (char *)malloc(100*sizeof(char));
}
函数执行之后,函数所在的栈被销毁,但是指针p仍然存在,p所指向的内存也没有被销毁,因为p指向的内存存放在堆上,而函数所在的栈被销毁与堆没有任何关系。因此,要记得释放已申请的资源。
堆与栈的区别
1.申请方式不同:栈是系统自动分配,堆需要自己申请,并申明大小。
2.申请后系统的响应方式不同:
栈:只要栈的剩余空间大于申请空间,申请就成功。否则抛出栈溢出异常。
堆:先遍历操作系统中记录空闲内存地址的链表,寻找第一个大于申请空间的堆节点,然后把该节点从空闲节点链表中删除,并将该节点的空间分配给程序。另外, 大多数操作系统会在这块内存空间首地址处记录本次分配的大小,以便于删除语句正确释放空间。若分配的堆节点大小有剩余,则将剩余部分自动记录到空闲节点链 表中。
3.申请大小限制不同。
栈:windows系统下栈的大小是2Mb,超出则溢出。因此能从栈获得空间较小。
堆:向高地址扩展的数据结构,是不连续的内存区域。堆的大小受限于系统中有效的虚拟内存。
MFC用new 和delete来分配和解除堆内存中的对象,在堆上分配对象的总大小只受系统虚拟内存大小的限制.
MFC提供的调试手段