替换STL的queue





 

替换STL的queue

http://blog.csdn.net/fxfeixue/article/details/7587381

分类: C/C++   25人阅读  评论(0)  收藏  举报
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_ */

替换了到自己的工程当中,编译,执行;等待中,等待出错,或者永远不出错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值