浅析C++野指针/delete

 本文中心问题是:C++中对指针执行delete操作后指针发生了什么变化?
 首先定义一个int型指针并进行new、delete。

/**
 * copyright 0.0.0.1
 * author:nine
 * 2019.7.20 for testing delete
 */
#include <iostream>
using namespace std;


int main(){
	int * p;
	cout << "--    define      --\n";
	cout << "p的地址:" << &p << endl;
	cout << "p对应的内存存储的地址:" << p << endl;
	cout << "p指向的内存地址对应的值:" << *p << endl;
	
	cout << "--    new     --\n";
	p = new int(10);
	cout << "p的地址:" << &p << endl;
	cout << "p对应的内存存储的地址:" << p << endl;
	cout << "p指向的内存地址对应的值:" << *p << endl;
	
	cout << "--    delete      --\n";
	delete p;
	cout << "p的地址:" << &p << endl;
	cout << "p对应的内存存储的地址:" << p << endl;
	cout << "p指向的内存地址对应的值:" << *p << endl;

	cout << "--    NULL      --\n";
	p = NULL;
	cout << "p的地址:" << &p << endl;
	cout << "p对应的内存存储的地址:" << p << endl;
	cout << "p指向的内存地址对应的值:" << *p << endl;
	return 0;
}	

 运行结果如下:

– define –
p的地址:0x60fe8c
p对应的内存存储的地址:0x4019ae
p指向的内存地址对应的值:1528349827
– new –
p的地址:0x60fe8c
p对应的内存存储的地址:0x1011728
p指向的内存地址对应的值:10
– delete –
p的地址:0x60fe8c
p对应的内存存储的地址:0x1011728
p指向的内存地址对应的值:16842944
– NULL –
p的地址:0x60fe8c
p对应的内存存储的地址:0
(空白行)

 在开始分析前先补充一下几个关于指针的基础知识:
  1.当一个变量被声明后就被系统分配了内存地址,所能存储的值的大小由声明时指定的类型决定,且变量能存储一个值,或字符或整型数值或其他;
  2.指针是一个变量,所以它有自己的内存地址;
  3.指针在内存中存储的是地址,地址对应的变量类型和指针被声明的类型一致。

分析

 从运行结果来看有几个比较直观的结论:
  1.在指针的整个生命周期中,指针本身的地址不变,无论是执行什么操作;
  2.delete操作改变的是指针所指向的内存地址上的值,并不是指针本身;
  3.delete操作之后指针所存储的地址没有发生改变。
  4.执行 p = NULL 之后,指针所存储的值被重置为NULL/0。


  执行new操作后,系统从堆空间分配了一部分内存空间给指针p,即指针p存储(指向)了一个内存地址。或者说,指针p能够使用该内存空间去执行一个合法操作而不会导致程序出现问题,如存储一个和指针的类型一致的值( int* p = new int(10)就是合法操作 )。

  而执行delete操作后,先前分配给指针p的内存空间被系统回收了,回收之后可能会分配给其他有需要的程序,但是p还是指向这个内存空间的(p还存储这这个内存空间的起始地址)。也就是说,指针p实际上还可以使用这个内存空间,但是任何利用这个内存空间的行为都是非法的,例如使用这个内存空间存储一个值,就可能会导致一些或小或严重的问题,因为系统回收这个内存空间后可能又将这个内存空间分配给系统程序了,而任意修改其他程序的数据有可能会导致该程序出错。**此时指针p就是野指针(悬空指针)。

  在计算机编程领域中,迷途指针,或称悬空指针、野指针,指的是不指向任何合法的对象的指针。
  当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍旧指向已经回收的内存地址,此情况下该指针便称迷途指针。若操作系统将这部分已经释放的内存重新分配给另外一个进程,而原来的程序重新引用现在的迷途指针,则将产生无法预料的后果。因为此时迷途指针所指向的内存现在包含的已经完全是不同的数据。通常来说,若原来的程序继续往迷途指针所指向的内存地址写入数据,这些和原来程序不相关的数据将被损坏,进而导致不可预料的程序错误。这种类型的程序错误,不容易找到问题的原因,通常会导致存储器区块错误(Linux系统中)和一般保护错误(Windows系统中)。如果操作系统的内存分配器将已经被覆盖的数据区域再分配,就可能会影响系统的稳定性
from 中文维基百科

消除野指针

  (在执行delete后)语句p = NULL执行的结果是p不再指向任何内存空间(p中存储的值为NULL/0),实际上就是彻底切断指针p和原来被分配到的内存空间之间的联系。这就避免了野指针的产生。

  但是如果在执行delete之前将p设置为NULL,那就是内存泄漏了,这同样会导致不好的后果。
野指针表情包


  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值