论android 中list erase用法

今天同事碰到一个有关list的问题,大神们可以一起讨论下 。
void clearBufList(){pthread_mutex_lock(&mMutex);DataBuf *buf;List::iterator item = mBufList.begin();for ( ; item != mBufList.end(); item++) {buf = *item;free(buf->data);delete buf;mBufList.erase(item);}pthread_mutex_unlock(&mMutex);}
函数的流程:
短时间看代码应该是没有问题的 。当然大神可能一眼就看出来了~~
先来一起看下item++ 和 erase:
inline _Iter& operator++() {// pre-incrementmpNode = mpNode->getNext();return *this;}const _Iter operator++(int) {// post-increment_Iter tmp(*this);mpNode = mpNode->getNext();return tmp;}
iterator erase(iterator posn) {_Node* pNext = posn.getNode()->getNext();_Node* pPrev = posn.getNode()->getPrev();pPrev->setNext(pNext);pNext->setPrev(pPrev);delete posn.getNode();return iterator(pNext);}
先来看erase 函数,假设有下面的一个链表:

论android 中list erase用法

文章插图
当想要移除2,erase 接口后Node 2 将会被,这个时候Node 2 将变成野指针(因为并没有置0的操作),Node 1 和Node 3 将连接起来 。
erase 后产生了一个新的,这个 中存放的是next node,而代码中忽略了这个返回值 。
再来看下post- 和pre-,两者的区别是pre- 返回了自身的 引用,而post- 返回的是一个新的 。
在这段代码中并没有出现item=item++ 或item=++item,当然因为前置就是自身,如果使用前置则不需要再赋值给item 自身 。
就post- 和pre- 函数本身是没有问题的,函数考虑将自身的node 移到下一个或者是Node Mid,然后返回一个(本身或者是一个新的) 。
但是,这段函数将erase 和item++ 做了结合,首先在erase 之后item 中的node 已经被 ,然后for 循环执行完erase 后会进行item++,而item++ 中需要做:
mpNode = mpNode->getNext();
论android 中list erase用法

文章插图
危险,这里的 已经在erase 的时候 掉了
所以,在使用list erase 的时候还是需要注意的,特别是在于item++ 结合使用的时候 。
其实,list.h 中已经给出了结合使用的方式:
【论android 中list erase用法】iterator erase(iterator first, iterator last) {while (first != last)erase(first++);// don't erase than incr later!return iterator(last);}
因为有些时候node 中存放的可能是一段,需要或者free,所以,都需要单独组合erase 和item++ 。我们可以采用上面的方式,在经过first++ 后,返回了一个新的 (里面存放的是旧的node)用于erase,而first 本身已经在++的时候将first 中的 切换成了next 。
另外一种方式可以是:
void clearBufList(){pthread_mutex_lock(&mMutex);DataBuf *buf;List::iterator item = mBufList.begin();for ( ; item != mBufList.end();) {buf = *item;free(buf->data);delete buf;item = mBufList.erase(item);}pthread_mutex_unlock(&mMutex);}
将erase 后的返回值赋值给item,因为erase 返回的是存放next node 的新的 。