1. malloc()函数
1.1 malloc的全称是memory allocation,中文叫动态内存分配, malloc与free是C++/C语言的标准库函数。 原型:extern void *malloc(unsigned int num_bytes);
说明:分配长度为num_bytes字节的内存块。若是分配成功则返回指向被分配内存的指针,分配失败返回空指针NULL。当内存再也不使用时,应使用free()函数将内存块释放。html
1.2 void *malloc(int size);
说明:malloc 向系统申请分配指定size个字节的内存空间,返回类型是 void* 类型。void* 表示未肯定类型的指针。C,C++规定,void* 类型能够强制转换为任何其它类型的指针。
备注:void* 表示未肯定类型的指针,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(好比是char仍是int或者...)c++
1.3 free
void free(void *FirstByte): 该函数是将以前用malloc分配的空间还给程序或者是操做系统,也就是释放了这块内存,让它从新获得自由。编程
1.4注意事项
1)申请了内存空间后,必须检查是否分配成功。
2)当不须要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面不当心使用了它。
3)这两个函数应该是配对。若是申请后不释放就是内存泄露;若是无端释放那就是什么也没有作。释放只能一次,若是释放两次及两次以上会出现错误(释放空指针例外,释放空指针其实也等于啥也没作,因此释放空指针释放多少次都没有问题)。
4)虽然malloc()函数的类型是(void *),任何类型的指针均可以转换成(void *),可是最好仍是在前面进行强制类型转换,由于这样能够躲过一些编译器的检查。数组
1.5 malloc()到底从哪里获得了内存空间?
答案是从堆里面得到空间。也就是说函数返回的指针是指向堆里面的一块内存。操做系统中有一个记录空闲内存地址的链表。当操做系统收到程序的申请时,就会遍历该链表,而后就寻找第一个空间大于所申请空间的堆结点,而后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。app
2. new运算符ide
2.1 C++中,用new和delete动态建立和释放数组或单个对象。函数
动态建立对象时,只需指定其数据类型,而没必要为该对象命名,new表达式返回指向该新建立对象的指针,咱们能够经过指针来访问此对象。
int *pi=new int;
这个new表达式在堆区中分配建立了一个整型对象,并返回此对象的地址,并用该地址初始化指针pi 。spa
2.2 动态建立对象的初始化操作系统
动态建立的对象能够用初始化变量的方式初始化。
int *pi=new int(100); //指针pi所指向的对象初始化为100
string *ps=new string(10,’9’);//*ps 为“9999999999”指针
若是不提供显示初始化,对于类类型,用该类的默认构造函数初始化;而内置类型的对象则无初始化。
也能够对动态建立的对象作值初始化:
int *pi=new int( );//初始化为0
int *pi=new int;//pi 指向一个没有初始化的int
string *ps=new string( );//初始化为空字符串 (对于提供了默认构造函数的类类型,没有必要对其对象进行值初始化)
2.3 撤销动态建立的对象
delete表达式释放指针指向的地址空间。
delete pi ;// 释放单个对象
delete [ ]pi;//释放数组
若是指针指向的不是new分配的内存地址,则使用delete是不合法的。
2.4 在delete以后,重设指针的值
delete p; //执行完该语句后,p变成了不肯定的指针,在不少机器上,尽管p值没有明肯定义,但仍然存放了它以前所指对象的地址,而后p所指向的内存已经被释放了,因此p再也不有效。此时,该指针变成了悬垂指针(悬垂指针指向曾经存放对象的内存,但该对象已经不存在了)。悬垂指针每每致使程序错误,并且很难检测出来。
一旦删除了指针所指的对象,当即将指针置为0,这样就很是清楚的指明指针再也不指向任何对象。(零值指针:int *ip=0;)
2.5 区分零值指针和NULL指针
零值指针,是值是0的指针,能够是任何一种指针类型,能够是通用变体类型void*也能够是char*,int*等等。
空指针,其实空指针只是一种编程概念,就如一个容器可能有空和非空两种基本状态,而在非空时可能里面存储了一个数值是0,所以空指针是人为认为的指针不提供任何地址讯息。参考:http://www.cnblogs.com/fly1988happy/archive/2012/04/16/2452021.html
2.6 new分配失败时,返回什么?
1993年前,c++一直要求在内存分配失败时operator new要返回0,如今则是要求operator new抛出std::bad_alloc异常。不少c++程序是在编译器开始支持新规范前写的。c++标准委员会不想放弃那些已有的遵循返回0规范的代码,因此他们提供了另外形式的operator new(以及operator new[])以继续提供返回0功能。这些形式被称为“无抛出”,由于他们没用过一个throw,而是在使用new的入口点采用了nothrow对象:
class widget { ... };
widget *pw1 = new widget;// 分配失败抛出std::bad_alloc
if (pw1 == 0) ... // 这个检查必定失败
widget *pw2 = new (nothrow) widget; // 若分配失败返回0
if (pw2 == 0) ... // 这个检查可能会成功
3. malloc和new的区别
3.1 new 返回指定类型的指针,而且能够自动计算所须要大小。
好比:
1) int *p;
p = new int; //返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);
或:
int* parr;
parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;
2) 而 malloc 则必需要由咱们计算字节数,而且在返回后强行转换为实际类型的指针。
int* p;
p = (int *) malloc (sizeof(int)*128);//分配128个(可根据实际须要替换该数值)整型存储单元,并将这128个连续的整型存储单元的首地址存储到指针变量p中
double *pd=(double *) malloc (sizeof(double)*12);//分配12个double型存储单元,并将首地址存储到指针变量pd中
3.2 malloc 只管分配内存,并不能对所得的内存进行初始化,因此获得的一片新内存中,其值将是随机的。
除了分配及最后释放的方法不同之外,经过malloc或new获得指针,在其它操做上保持一致。
4.有了malloc/free为何还要new/delete?
1) malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们均可用于申请动态内存和释放内存。
2) 对于非内部数据类型的对象而言,光用maloc/free没法知足动态对象的要求。对象在建立的同时要自动执行构造函数,对象在消亡以前要自动执行析构函数。因为malloc/free是库函数而不是运算符,不在编译器控制权限以内,不可以把执行构造函数和析构函数的任务强加于malloc/free。
所以C++语言须要一个能完成动态内存分配和初始化工做的运算符new,以及一个能完成清理与释放内存工做的运算符delete。注意new/delete不是库函数。咱们不要企图用malloc/free来完成动态对象的内存管理,应该用new/delete。因为内部数据类型的“对象”没有构造与析构的过程,对它们而言malloc/free和new/delete是等价的。3) 既然new/delete的功能彻底覆盖了malloc/free,为何C++不把malloc/free淘汰出局呢?这是由于C++程序常常要调用C函数,而C程序只能用malloc/free管理动态内存。若是用free释放“new建立的动态对象”,那么该对象因没法执行析构函数而可能致使程序出错。若是用delete释放“malloc申请的动态内存”,结果也会致使程序出错,可是该程序的可读性不好。因此new/delete必须配对使用,malloc/free也同样。