关于野指针

16 篇文章 0 订阅

所谓的野指针,实际上就是指针内存释放了之后,还继续调用,然后造成堆破坏。

这样的错误在刚开始是检测不出来的,只有在New的时候进行堆检测才会检测出来。


下面是我遇到的一个野指针,很隐蔽。只是有概率的出现野指针。

这是一个多线程的问题,首先在主线程进行removeSocket(),正常情况下,removeSocket会执行break,子线程是一个循环

				while (getNowSocket() && getNowSocket()->GetSocketStatus()==SOCKET_STATUS_CONNECT)
				{
					if(this->getNowSocket()->OnSocketNotifyRead() == -1)
					{
						break;
					}
				}

下面是removeSocket的方法

//移除套接字
	void removeSocket(){ 
		if(m_pSocket != NULL)
		{
			if(m_pSocket->GetSocketStatus()==SOCKET_STATUS_CONNECT) 
			{
				m_pSocket->CloseSocket(); 
			}
                        if(m_pSocket != NULL) CC_SAFE_DELETE(m_pSocket);
		}
	};


也就是会调用removeSocket来delete socket;

这样做是十分危险的,因为虽然在循环里调用了break进行清除,但是由于网络的不确定性,很可能在你清除Socket的时候,刚好运行到循环判断的时候,这样就造成了野指针,然后程序崩溃。所以delete socket可以转到线程结束的时候调用。



9.17补充:

其实上面所说的并非是真正造成野指针的原因,真正的原因还在多线程的使用,主线程调用removeSocket是执行关闭Socket,但是在关闭的某一时刻子线程就已经知道主线程要关闭Socket了,就会自动执行关闭代码,如果照原来的写法,在线程结束的时候调用,也有可能在线程结束的时候removeSocket没有执行完,造成野指针。


下面是给出的解决方法,有两种:

1.退出的线程并不执行delete操作,每次调用网络循环子线程的时候检测变量是否存在,如果存在就delete

2.做一个状态变量,当removeSocket执行完成的时候状态设为完全关闭,在子线程中使用循环检测,如果没有完全关闭,则循环等待,如果完全关闭则delete


第一种方法简单方便,第二种方法逻辑上略复杂,而且略代码冗余。

但是第二种方法可以及时释放内存,使用哪种方法就见仁见智咯。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值