目测是一帮菜逼,因为搞不清释放内存前后的缘由,把STL改了。
事情的起因很好笑,但是修改STL的过程比较经典,值得学习,大家当STL解析教程来看吧。
原文地址:http://www.rosoo.net/a/201012/10617.html
STL库是个伟大的作品,不过,有的时候,它也有一点点小问题。
我写的一个服务器程序,在运行大约8小时候,出现Program received signal SIGSEGV, Segmentation fault.
#1 0x00002adde5c9a853 in _int_free () from /lib64/libc.so.6
#2 0x00002adde5c9a99c in free () from /lib64/libc.so.6
下面一级堆栈是
m_queuefreep->pop();
下面是源码:
data_t *try_get_free_data() { boost::mutex::scoped_try_lock lock(m_free_mutex); if(!lock.owns_lock()) { return NULL; } if(m_queuefreep->empty()) { return NULL; } data_t* datap = m_queuefreep->front(); m_queuefreep->pop(); return datap; };
这个队列,我只是用来存放结构体指针,而且已经加锁保护;
m_queuefreep->pop()的过程中,会调用free()函数,free一个指针类型;
这没有必要free的阿。
经过仔细分析,可以确认自己的代码没有问题。
百度到了一篇文章:《谁知道malloc_consolidate是个什么函数》
这位老兄,也碰到类似的问题,他提出的解决办法是替换queue。
《std::queue.pop()的怪异问题:多线程环境下,pop()将调用对象的析构函数》
这位老兄,也一样,碰到过这个问题。
这位老兄的模板类写的非常好,收录如下:
#include <stdexcept> // for debug purpose template <typename item, unsigned int qsize> class queue { public: item data[qsize]; unsigned int rp,wp; bool full; queue(): rp(0),wp(0),full(false) {} bool empty() { return ((rp == wp) && (!full)); } unsigned int size() { if(!full) return (wp-rp+qsize)%qsize; else return qsize; } item& front() { if(empty()) throw; return data[rp]; } item& back() { if(empty()) throw; return data[(wp-1+qsize)%qsize]; } void push(const item dd) { if(full) throw; data[wp] = dd; wp = (wp+1)%qsize; if(wp == rp) full = true; } void pop(){ if(empty()) throw; rp = (rp + 1)%qsize; full = false; } }; template <typename item, unsigned int qsize> class stack { public: item data[qsize]; unsigned int p; stack(): p(0){} bool empty() { return (p == 0);} unsigned int size() { return p; } item& top(){ if(empty()) throw; return data[p-1]; } void push(const item dd) { if(p==qsize) throw; data[p++] = dd; } void pop() { if(empty()) throw; p--; } };
并略加修改:
/* * myqueue.h * meant to replace the STL queue. * Created on: 2010-3-19 * Author: guoqiang */ #ifndef MYQUEUE_H_ #define MYQUEUE_H_ #include <stdlib.h> #include <exception> #include <stdexcept> // for debug purpose using namespace std; template <typename item> class gqueue { public: gqueue(int capacity): m_rp(0), m_wp(0), m_full(false) { m_capacity = capacity; m_datap = (item*)malloc(sizeof(item)*m_capacity); if(m_datap == NULL) { throw(exception()); } } virtual ~gqueue() throw() { if(m_datap) { free(m_datap); m_datap = NULL; } }; bool empty() { return ((m_rp == m_wp) && (!m_full)); } unsigned int size() { if(!m_full) { return (m_wp-m_rp+m_capacity)%m_capacity; } else { return m_capacity; } } item& front() { if(empty()) { throw; } return m_datap[m_rp]; } item& back() { if(empty()) { throw; } return m_datap[(m_wp-1+m_capacity)%m_capacity]; } void push(const item dd) { if(m_full) { throw; } m_datap[m_wp] = dd; m_wp = (m_wp+1)%m_capacity; if(m_wp == m_rp) { m_full = true; } } void pop() { if(empty()) { throw; } m_rp = (m_rp + 1)%m_capacity; m_full = false; } private: unsigned int m_capacity; // item data[qsize]; item* m_datap; unsigned int m_rp; unsigned int m_wp; bool m_full; }; #endif /* MYQUEUE_H_ */
替换了到自己的工程当中,编译,执行;等待中,等待出错,或者永远不出错。
原文来自:http://hi.baidu.com/goggle1/blog/item/0ea14befc4675ef7b2fb952a.html