在C++中,内存分红5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。程序员
在执行函数时,函数内局部变量的存储单元均可以在栈上建立,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,可是分配的内存容量有限。
是由编译器在须要时自动分配,不须要时自动清除的变量存储区。一般存放局部变量、函数参数等。windows
就是那些由new分配的内存块,他们的释放编译器不去管,由咱们的应用程序(程序员)去控制,通常一个new就要对应一个delete,一个new[]与一个delete[]对应。若是程序员没有释放掉,那么在程序结束后,操做系统会自动回收。数组
就是那些由malloc等分配的内存块,他和堆是十分类似的,不过它是用free来结束本身的生命的。数据结构
全局变量和静态变量被分配到同一块内存中(在之前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。)函数
这是一块比较特殊的存储区,他们里面存放的是常量,不容许修改。操作系统
(注意:堆和自由存储区其实不过是同一块区域,new底层实现代码中调用了malloc,new能够当作是malloc智能化的高级版本)指针
堆: 操做系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,而后将该结点从空闲结点链表中删 除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码 中的delete语句才能正确的释放本内存空间。咱们常说的内存泄露,最多见的就是堆泄露(还有资源泄露),它是指程序在运行中出现泄露,若是程序被关闭掉的话,操做系统会帮助释放泄露的内存。code
栈: 在函数调用时第一个进栈的主函数中的下一条指令(函数调用语句的下一条可执行语句)的地址而后是函数 的各个参数,在大多数的C编译器中,参数是由右往左入栈,而后是函数中的局部变量。对象
管理方式:队列
系统响应:
空间大小:
碎片问题:
生长方向:
分配方式:
分配效率:
(1)指针变量没有被初始化。任何指针变量刚被建立时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。因此,指针变量在建立的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。
(2)指针p被free或者delete以后,没有置为NULL,让人误觉得p是个合法的指针。
malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。 它们均可用于申请动态内存和释放内存。
对于非内部数据类型的对象而言,光用maloc/free没法知足动态对象的要求。对象在建立的同时要自动执行构造函数,对象在消亡以前要自动执行析构函数。因为malloc/free是库函数而不是运算符,不在编译器控制权限以内,不可以把执行构造函数和析构函数的任务强加于malloc/free。
所以C++语言须要一个能完成动态内存分配和初始化工做的运算符new,以及一个能完成清理与释放内存工做的运算符delete。注意new/delete不是库函数。
既然new/delete的功能彻底覆盖了malloc/free,为何C++不把malloc/free淘汰出局呢?这是由于C++程序常常要调用C函数,而C程序只能用malloc/free管理动态内存。
若是用free释放“new建立的动态对象”,那么该对象因没法执行析构函数而可能致使程序出错。若是用delete释放“malloc申请的动态内存”,结果也会致使程序出错,可是该程序的可读性不好。因此new/delete必须配对使用,malloc/free也同样。
C++ 提供了一种“动态内存分配”机制,使得程序能够在运行期间,根据实际须要,要求操做系统临时分配一片内存空间用于存放数据。此种内存分配是在程序运行中进行的,而不是在编译时就肯定的,所以称为“动态内存分配”。
在 C++ 中,经过 new 运算符来实现动态内存分配。
new 运算符的第一种用法:
T \*p = new T; 其中,T 是任意类型名,p 是类型为 T\* 的[指针] **new 运算符还有第二种用法,用来动态分配一个任意大小的数组:**
T *p =new T[N];
//其中,T 是任意类型名,p 是类型为 T* 的指针,N 表明“元素个数”,能够是任何值为正整数的表达式,表达式中能够包含变量、函数调用等。这样的语句动态分配出 N × sizeof(T) 个字节的内存空间,这片空间的起始地址被赋值给 p。
程序从操做系统动态分配所得的内存空间在使用完后应该释放,交还操做系统,以便操做系统将这片内存空间分配给其余程序使用。C++ 提供 delete 运算符,用以释放动态分配的内存空间。delete 运算符的基本用法以下:
delete p;
若是是用 new 的第二种用法分配的内存空间,即动态分配了一个数组,那么释放该数组时,应以以下形式使用 delete 运算符:
delete\[\] p;
牢记,用 new 运算符动态分配的内存空间,必定要用 delete 运算符释放。不然,即使程序运行结束,这部份内存空间仍然不会被操做系统收回,从而成为被白白浪费掉的内存垃圾。这种现象也称为“内存泄露”。