malloc和free ,new 和delete
1. free 和delete 究竟把指针怎么了?
答:他们只是把指针所指的内存释放掉了,并没有把指针本身怎么样
1. 动态内存会被自动释放吗?
不会。
(一) 指针消亡了,并不表示它所指向的内存被自动释放
(二) 内存被释放了,并不表示指针会消亡或者成为NULL;
两步:free(p);
p = NULL;
1. 杜绝野指针
“野指针”不是NULL指针,而是指向垃圾内存的指针,if 语句对野指针不起作用。
原因:
(一) 指针变量没有被初始化,任何指针变量在创建时,都不会自动成为NULL指针,它的缺省值是随机的,所以指针变量在创建的同时应该就要完成初始化工作,要么初始化为NULL,要么指向合法的内存
(二) 指针被free 或者delete 之后,没有置为NULL,
(三) 指针操作超越了变量的作用范围。
1. 有了malloc 和 free ,为什么还要有 new 和delete
Malloc和free 是c/c++的库函数,new和delete是c++中的运算符
对于非内部数据类型,光用malloc和free 无法满足动态对象的要求:(因为对象在创建的时候要自动调用构造函数,对象在析构的时候,要自动调用析构函数)由于malloc和free是库函数而不是运算符,不在编译器的控制权限之内,new/delete 不是库函数,是运算符。
#include<iostream>
using namespace std;
class Object
{
public:
Object(void)
{
cout<<"Obiect()"<<endl;
}
~Object(void)
{
cout<<"~Object()"<<endl;
}
void Initlize(void)
{
cout<<"Initlize"<<endl;
}
void Destroy(void)
{
cout<<"Destroy"<<endl;
}
};
/*
int main()
{
Object *a = (Object*)malloc(sizeof(Object));//申请动态内存
a->Initlize();//初始化,模拟了构造函数的功能,
a->Destroy();//清除,模拟了析构函数的功能,因为malloc/free 不能执行构造函数与析构函数,
//所以必须调用成员函数来完成初始化和清除工作。
free(a);//释放
return 0;
}*/
int main()
{
Object *a = new Object;//调的是构造函数和析构函数
delete a;
}
所以我们不要企图用malloc/free来完成动态对象的内存管理,应该用new/delete,由于内部数据类型的“对象”没有构造函数和析构函数,所以new/delete malloc/free 对他们来说都是等价的。
既然new/delete功能完全覆盖了malloc/free,为什么不把malloc/free/淘汰?
因为c++程序经常要调用c语言程序,而c程序只能用malloc/free/管理动态内存。
1. malloc 和 free 的使用要点:
malloc 的原型:void* malloc(size_t size);
int *p = (int *)malloc(sizeof(int)*length);
两大元素:“类型转换”“大小(sizeof)”
malloc返回值类型是void* 所以在调用的时候要显式的进行类型转换,将void * 转换为所需要的指针类型
函数free原型:
Void free(void * memblock);
为什么free不像malloc 那样复杂呢?
因为p的类型以及它所指向的内存的容量都是知道的,如果p是NULL指针,那么对p释放多少次都是没关系的,但是如果p不是空指针,对p连续释放两次就会出现问题,导致程序出现错误。
2. new 和delete的使用要点:
int *p1 = (int *)malloc(sizeof(int)*length);
int *p2 = new int[length];
new 使用起来比malloc方便的多:因为new 中内置了sizeof,类型转换,类型安全检查等功能,对于非内部数据类型的对象而言,new在创建动态对象的同时完成了初始化工作,如果有多个构造函数,那么new 的语句也可以有多种形式。
Class Obj
{
Public:
Obj(void)//无参构造函数
Obj(int x);//带一个参数的构造函数
};
Void main()
{
Obj *a = new Obj;
Obj *b = new Obj(1);//初值为1
delete a;
delete b;
}
如果用new 创建对象数组,只能使用对象的无参构造函数
Obj *object = new Obj[100];
不能这样: Obj *object = new Obj[100](1);
delete[]objects;
delete objects;//相当于delete object[0];漏掉了99个对象。