目测是一帮菜逼,因为搞不清释放内存前后的缘由,把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

 

 

 

posted on 2012-10-19 16:51  林子好  阅读(2670)  评论(0编辑  收藏  举报

导航