析构函数使用不当造成操作野指针程序coredump

来源:互联网 发布:sql 注入 php 提权 编辑:程序博客网 时间:2024/06/09 23:08

实现了一段定时器程序代码,其中使用了list来存储一个结构timerNode,并在list类中的析构函数实现了对该timerNode的一段操作,该操作是要将该list清空,但是不会释放内存

1.timerList类的部分实现:

CTimerList::CTimerList():m_head(NULL),m_tail(NULL){}CTimerList::~CTimerList(){   while(NULL!=m_head)   {      (void*)removeHead();   }}

2.timerManager中析构函数实现:

CTimerManager::~CTimerManager(){    m_workThread->stop();    m_timeOutThread->stop();    m_timerThread->stop();    pthread_cond_broadcast(&m_cond);    pthread_cond_broadcast(&m_timeOutCond);        DELETE(m_timeOutList);    delete[] m_workList;    m_workList=NULL;    timer(m_baseUnit*1000);    DELETE(m_workThread);    DELETE(m_timeOutThread);    DELETE(m_timerThread);    for(int i=0; i<m_firstIndex;i++)    {        timerNode* pNode=m_pTimerLock[i];        delete[] pNode;    }    pthread_cond_destroy(&m_cond);    pthread_cond_destroy(&m_timeOutCond);    pthread_mutex_destroy(&m_mutex);    m_baseUnit=0;}

从上面可以看到了对内存释放是先释放了list,然后释放Node的动态数组,写到这个位置的时候,楼主感到一点不安,但是也只是一闪而过而已并没有过多的怀疑这个写法有没有问题,下面是分配Node的地方:

3.alloccNode:

int CTimerManager::allocNewNode(){   if(m_firstIndex==TIMERFIRSTINDEX)   {       return -1;   }   timerNode* pNode=new timerNode[TIMERSECONDINDEX];   if(NULL==pNode)   {      return -2;   }   for(int i=0; i<TIMERSECONDINDEX; i++)   {      m_idleList.addTail(&pNode[i]);      pNode[i].m_root=&m_idleList;      pNode[i].timerID.bit_s.firstIndex=m_firstIndex;      pNode[i].timerID.bit_s.secondIndex=i;   }   m_pTimerLock[m_firstIndex]=pNode;   m_firstIndex++;   return 0;   }


从这段代码中我们基本上可以看出来还存在一个list,这个list并不是动态分配而是栈分配的,同时所有的timerNode并不是单独分配的,而是通过一个指针数组指向了一段又一段连续的地址,该内存只能够使用delete[]的方式,但是如果按照上面的代码所写的话,依旧会出现coredump,而coredump的位置是:
(void*)removeHead();
为什么呢出现这个情况呢?
原因其实就在于m_idleList,这个变量是属于栈分配的,栈分配的内存只有在变量生命周期结束的时候才会进行释放,在这段程序中只有当main函数执行结束的时候,才会释放。也就是当释放m_idleList并最新list类析构函数的时候,list中的元素都已经处于野指针状态了,因此程序就coredump了。
所以我们应该怎么进行释放呢,首先就是在list析构函数中不要使用node内存进行操作,而是直接将指针置为空的方式。



0 0
原创粉丝点击