对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。
由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
new和delete是运算符不是函数
因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。new/delete不是库函数,而是运算符。
int *p1=new int(1); //pi指向一个动态分配的、初始化值为1的无名对象int *p2(new int(1)); //同上
br
vector<int> *vec = new vector<int> { 1, 2, 3, 4, 5 };int *arr = new int[3] {1, 2, 3};int *p = new int { 1 };
br
br
br
br
Foo* factory(T arg){...return new Foo(arg);}
void use_factory(T arg){Foo *p=factory(arg);}
void use_factory(Foo arg){Foo *p=factoyr(arg);...delete p;}
int *p=new int(30); //申请......delete p; //释放p=nullptr; //置位空
实际上,作为初级程序员容易犯这样的错误,认为只要delete之后,自己就不负责任了(实际上你这种行为和渣男有什么区别,明明已经和你的前女友分手了,你还留着人家的各种信息和人家藕断丝连,偶尔还用保存着前女友的某一个把柄来威胁前女友。)我曾经犯过这样错误,导致游戏服务器的一个全球跨服战的宕机,原因就是我在delete之后,没有将指针指向的内容没有置为NULL,导致我后面又对指针指向的成员进行非法访问,宕机,我半夜两天起来远程连接公司电脑修BUG,到现在记忆犹新,心脏瞬间不好了。
特点
br
使用规则
shared_ptr<int> p=new int(1024); //错误shared_ptr<int> p2(new int(1024)); //正确:使用直接初始化
shared_ptr<int> clone(int p){return new int(p); //错误}shared_ptr<int> clone(int p){return shared_ptr<int>(new int(p)); //正确}
void process(shared_ptr<int> ptr){ ... }shared_ptr<int> p(new int(42)); //初始化一个智能指针对象pprocess(p); //p所指的对象引用计数加1//process函数调用之后,p所指的引用计数减1int i=*p; //正确
void process(shared_ptr<int> ptr){ ... }int *x(new int(1024));process(x); //错误,不能将int*转换为一个shared_ptr<int>process(shared_ptr<int>(x)); //合法的,但是process函数返回之后内存会被释放int j = *x; //错误,x所指的内存已经被释放了
br
十二: 动态数组的初始化
br
int *p1 = new int[3]{1,2,3}; //动态数组int p2[3]= { 1,2,3 }; //普通数组
for (int i = 0; i < 3; i++) //正确cout <<p1[i] << endl;for each (int var in p2)//错误{
}
int arr[0]; //错误int *p = new int[0]; //正确
typedef int arrT[10];int *a=new arrT;delete []a;实际上我要解释下:delete a; 仅释放了a指针指向的全部内存空间 但是只调用了a[0]对象的析构函数剩下的从a[1]到a[9]这9个用户自行分配的m_cBuffer对应内存空间将不能释放 从而造成内存泄漏。delete [] a; 调用使用类对象的析构函数释放用户自己分配内存空间并且释放了a指针指向的全部内存空间所以总结下就是,如果ptr代表一个用new申请的内存返回的内存空间地址,即所谓的指针,那么:delete ptr 代表用来释放内存,且只用来释放ptr指向的内存。
delete[] rg 用来释放rg指向的内存,!!还逐一调用数组中每个对象的destructor 对于像int/char/long/int*/struct等等简单数据类型,由于对象没有destructor,所以用delete 和delete [] 是一样的!但是如果是C++对象数组就不同了!我将会在接下来的第28节说到这块