1.new与delete运算
c++提供了两个中重要的运算符:new和delete。由于他们是运算符不是函数,因此执行效率更高。
运算符 | 功能 | 目 | 结合性 | 用法 |
---|---|---|---|---|
new[] | 动态分配 | 单目 | 自右向左 | new type |
new[] | 动态分配数组 | 单目 | 自右向左 | new type[] |
delete | 释放空间 | 单目 | 自右向左 | delete expr |
delete[] | 释放数组空间 | 单目 | 自右向左 | delete []expr |
new 运算符将在自由存储区中动态分配内存,创建对象,一般形式为:
(1)分配指定类型的内存空间,且指定初值:
new 类型
(2)分配指定类型的内存空间,且指定初值:
new 类型(初值)
(3)分配一个(一维或多维数组):
new 类型[常量表达式]…
new运算结果是指向分配得到的内存空间的指针,如果没有足够的内存空间可以分配,其运算结果是一个0值指针。
例如
int *p1,p2;
char *pz1,*pz2;
p1=new int; //分配一个整形空间,若成功则p1指向该空间,否则p1为NULL
p2=new int(10); //分配一个整形空间,且给整个整形赋初值10,即*p2为10
pz1=new char[80]; //分配一个字符数组(字符串)空间,即pz1为字符串指针
pz2=new char[5][80]; //分配一个二维字符串(字符串数组)空间,即pz1为字符串数组指针
delete运算符释放内存返回给自右存储区,销毁对象,一般形式为
(1)释放已分配的内存空间
delete 指针表达式
(2)释放已分配的数组内存空间
delete [] 指针表达式
delete运算释放指针所指向的内存空间,第(3)种new形式分配的数组内存空间需要用第(2)种delete形式来释放。
例如:
delete p1; //释放p1指向的整形空间
delete []pz1; //释放pz1指向的字符串空间
delete []pz2; //释放pz2指向的字符串数组空间
销毁对象后,指针p1变得没有定义,然而它仍然存在先前所指向的对象(已销毁)的地址,因此指针p1不再有效,成这样的指针为悬垂指针。悬垂指针指向曾经有效的对象内存,但该对象已经不再存在。使用垂悬指针往往导致程序错误,而且很难检测出来糖厂在delete运算之后将指针重设为0值指针,避免垂悬指针。
用new创建的动态对象使用完之后,必须用delete销毁。若是0值指针,delete运算不起任何作用。
int *p=0;
delete p; //使用正确,无意义
//delete只删除由new创建的动态对象,否则将导致程序错误。例如:
int a,*p=&a,*p1;
string str="hello";
p1=new int(100);
delete p1; //正确
delete str; //错误,str不是动态对象
delete p; //错误,p所指向的a是静态分配寻出空间的。
2.动态内存分配函数
(1)malloc函数
malloc函数用于分配一个指定大小的内存空间,函数原型为:
void *malloc(size_t size);
若分配成功,函数返回一个指向该内存空间起始地址的viod类型指针;若分配失败,函数返回0值指针NULL。参数size表示申请分配的字节数,类型size_t一般为unsigned int。
在实际编程中,malloc函数返回的void类型指针可以显示转换为其他类型的指针。调用函数时,一般使用sizeof来计算内存的大小,需要注意的是,分配的到的内存空间是未初始化的,即内存中的数据不是确定的。
例如
int *p=(int)malloc(sizeof(int))
若分配成功,p指向分配得到的内存单元,*p表示该内存单元。
(2)calloc函数
calloc函数用于分配n个连续的指定大小的内存空间,函数原理为:
void malloc(size_t nmemb,size_t size)
每个内存空间的大小为size字节,总字节数为n*size,并且将分配得到的内存空间的地址全部初始化为0.若分配成功,指向分配内存空间的起始地址,若失败,返回0值指针NULL
例如,分配20个int类型(相当于int p[20])内存空间
int *p=(int *)calloc(20,sizeof(int));
等价于
int *p=(int *)malloc(20*sizeof(int));
3、动态内存的调整函数
realloc函数用于调整已分配内存空间的大小,函数原型为:
void *realloc(void *ptr,size_t size);
realloc将指针ptr所指向的动态内存空间扩大或者缩小为size大小,无论扩大或者缩小,原内存中的饿内容不变。缩小空间会丢失缩小的那部分内容(假如内存缩小为原来的一般,则原来地址的后半部分消失;如果增加也是增加到原来地址的后半部分),
例如:
int *p;
p=(int *)malloc(20*sizeof(int));
p=(int *)realloc(10*sizeof(int));
p=(int *)realloc(60*sizeof(int));
4、动态内存释放函数
free函数用来释放动态分配的内存空间,函数原型为:
/*ptr指向已有的动态内存空间,如果ptr为空,什么操作也不执行*/
void free(void *ptr);
在实际编程中,若某个动态分配的内存不再使用时,应该及时将其释放。在动态分配的内存释放后,就不能再通过指针去访问,否则会导致程序出现崩溃。
通常,ptr释放后,需要设置ptr为NULL,避免产生“迷途指针”。
int *p;
p=(int *)malloc(sizeof(int));
free(p);
p=NULL;