首先看一下定义:
new 和 delete 是两个运算符, 是C++的东西(C没有) ,用于管理 堆内存 的。
它封装了C中的 malloc 和 free 函数
new 在申请内存的同时,还会调用对象的构造函数。
delete 在释放内存之前,会调用对象的析构函数。
malloc 只会申请内存, free 只会释放内存。
以上说法都没毛病 但不是今天的重点
重点是: delete释放内存时做了什么
看个例子:
int a = 200;
int *p = new int(a);
printf("----*p = %d\n",*p); //结果为200 (1)
delete p;
printf("—————*p = %d\n",*p); //结果为0 (2)
首先 new了一个指针p
并指向了一块内存
p中存的是该内存的地址 这基本上是指针的定义了
但是 这块内存并不是a
int *p = new int(a); 这句:只是用a的值初始化了p指向的内存 即就是:p指向的内存的值为a
也就是200 。 p并没有指向a 也就是p存的并不是a的地址。
所以(1)的结果为200
那么delete呢
在delete之前 这块内存已经被占用(存了200) 在任何时候 系统不可能将该内存分配给其他使用者
delete 关键字会告诉系统 这块内存可以被重新申请了,你拿去用吧!!!
但是 此时p指向的还是这块内存 除非改变p的指向
所以啊 在delete之后最好 p = NULL 将指针指向空
这样做的目的是: 假如p原来指向的内存的值为 200 在delete之后 系统将这块内存的值改为300, 你还不知道,此时p还是指向该内存。此时用p来取这块内存的值 结果就是300啦, 明显不符合你的想法,但是编译器不会报错。 但是 p = NULL 后,你再使用p的时候就会告诉你 这是一个空指针,就会报错…………
还有一个问题
看例子:
int a = 200;
int b = 500;
int *p = new int(a);
printf("----*p = %d\n",*p);
p = &b; //(1)
printf("____*p = %d\n",*p);
delete p;
p = NULL;
return 0;
上面的代码运行 毫无疑问 会崩溃
但是注释(1) 这行 就正常了
原因如下:
(1)p原来指向的地址成了内存泄漏(new int产生的地址) ,因为没释放
(2)p原先指向的是堆内存, 后续操作已经指向局部变量(栈空间)对象地址了
而栈空间是无须进行delete的
所以造成了上面的问题
程序员不可能不犯错误 即使你很牛逼 故 三十六计 细心为上策 遇事多思考 要不断学习新知识,温习旧能力