删除指向指针数组的指针

有以下代码:

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. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性