删除指向指针数组的指针
有以下代码:
int **p;
p = new int*[5];
表示p为一个指向int型指针的指针,指向了一个int型数组的首地址,该数组中存放的int型指针
我们如何释放p对应的空间呢?
for(int i = 0; i < 5; i++)
{
if(p[i] != NULL)
{
delete p[i]; // 删除数组中的int型指针p[i]
p[i] = NULL; // 同时将该指针指向空
}
delete[] p; // 删除数组指针p
}
野指针
以下代码:
int *p = new int(5); // 表示一直指针p,指向一个空间,该空间存放一个5
如果我们delete
他
delete p;
那么结果是,该空间中的内容被删除,即该空间被释放,但p依旧指向该空间,此时如果再次调用
delete p;
那么就会报错,因为p成为了野指针,就是,指向一个空间,但该空间中什么也没有。
并且C++编译器也没法识别这个指针是否为野指针,我们也没法让程序识别。
一般情况下不会有问题,但如果我们想进行以下操作:
class A
{
public:
int **p; // p为指向int型指针的指针
p = new int*[5]; // 此时p为一个指针,指向一个地址,该地址中存放的为一个数组的首地址,这个数组长度为5,且里面的元素为int型指针。
A()
{
for(int i = 0; i < 5;i++)
p[i] = NULL; // 此时p[i] 这个指针就不再是野指针,而成为了一个指向NULL的指针
}
~A()
{
// 析构函数
}
};
// 我们进行赋值
for(int i = 0; i < 5; i++)
p[i] = new int(i); // 此时,*p[i] = i
// 我们为了某个目的,需要将p[2] 的空间释放,也就是执行 delete p[2]的操作:
delete p[2]; // 此时p[2] 仍然指向原来的空间,但原来的空间被释放,且里面什么也没有
此时如果我们需要对上述类的内容进行析构
我们这么编写析构函数:
~A()
{
for(int i = 0; i < 5; i++)
delete p[i]; // 释放数组中的指针
delete[] p; // 释放指向数组的指针
}
释放过程是没有问题的,但是,因为我们之前执行过这个操作:
delete p[2];
这个操作已经对\(p[2]\) 中的地址进行了释放,此时析构函数就对同一块地址进行了重复释放,就会导致内存错误
如果我们对析构函数进行以下更改:
~A()
{
for(int i = 0 ; i < 5; i++)
{
if(p[i] == NULL)
continue; // 释放过的就跳过
delete p[i];
}
delete[] p;
}
但问题又来了,我们当时释放\(p[2]\) 的时候,只是delete
了一下,没有将p[2]
指向\(NULL\),所以析构函数中的\(if\)语句仍然无法识别我们的意图,仍然对同一块地址重复释放。
所以,我们必须养成良好的习惯:
当我们释放某个指针\(p\)对应的地址的时候,我们不仅要
delete p; // 释放p指向的地址
还要将\(p\)指向\(NULL\)
也就是完整的释放过程应该为以下两条语句:
delete p;
p = NULL;
原文地址:http://www.cnblogs.com/hi-wind/p/16861509.html
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请务用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性