0

为我的应用修改了以下循环队列代码。

该队列最多可容纳 32 个元素,我已将这些元素声明为类中的结构数组。要将元素添加到队列中,您必须调用 CreateElement() 函数,该函数会检查空闲元素并返回索引。当我在处理 CreateElement 函数中的以下行后重用元素时崩溃

    boost::shared_array<char> tData(new char[bufferSize]);

    m_QueueStructure[queueElems].data = tData;

根据文档,赋值运算符应该销毁早期的对象并分配新的对象。为什么会崩溃?谁能告诉我我在哪里搞砸?

#include "boost/thread/condition.hpp"
#include "boost/smart_ptr/shared_array.hpp"
#include <queue>

#define MAX_QUEUE_ELEMENTS 32

typedef struct queue_elem
{
    bool            inUse;
    int             index;
    int             packetType;
    unsigned long   compressedLength;
    unsigned long   uncompressedLength;
    boost::shared_array<char> data;
}Data;

class CQueue
{
private:
    int                         m_CurrentElementsOfQueue;
    std::queue<Data>            the_queue;
    mutable boost::mutex        the_mutex;
    boost::condition_variable   the_condition_variable;
    Data                        m_QueueStructure[MAX_QUEUE_ELEMENTS];

public:

    CQueue()
    {
        m_CurrentElementsOfQueue = 0;

        for(int i = 0; i < MAX_QUEUE_ELEMENTS; i++)
        {
            m_QueueStructure[i].inUse = false;
            m_QueueStructure[i].index = i;
        }
    }

    ~CQueue()
    {
        for(int i = 0; i < m_CurrentElementsOfQueue; i++)
        {
            int index = wait_and_pop();

            Data& popped_value = m_QueueStructure[index];

            popped_value.inUse = false;
        }
        m_CurrentElementsOfQueue = 0;
    }

    void push(Data const& data)
    {
        boost::mutex::scoped_lock lock(the_mutex);

        the_queue.push(data);

        lock.unlock();      

        the_condition_variable.notify_one();
    }

    bool empty() const
    {
        boost::mutex::scoped_lock lock(the_mutex);
        return the_queue.empty();
    }

    bool try_pop(Data& popped_value)
    {
        boost::mutex::scoped_lock lock(the_mutex);
        if(the_queue.empty())
        {
            return false;
        }

        popped_value=the_queue.front();
        the_queue.pop();
        return true;
    }

    int wait_and_pop()
    {
        boost::mutex::scoped_lock lock(the_mutex);

        while(the_queue.empty())
        {
            the_condition_variable.wait(lock);
        }

        Data& popped_value=the_queue.front();

        the_queue.pop();

        return popped_value.index;
    }

    int CreateElement(int bufferSize, unsigned long _compressedLength, 
        unsigned long _uncompressedLength, int _packetType) /* Send data length for this function */
    {

        int queueElems = 0;

        if(m_CurrentElementsOfQueue == 32)
        {
            CCommonException ex(QERROR, QUEUE_FULL, "Circular Buffer Queue is full");
            throw ex;
        }

        for(queueElems = 0; queueElems < MAX_QUEUE_ELEMENTS; queueElems++)
        {
            if(m_QueueStructure[queueElems].inUse == false)
                break;
        }

        boost::shared_array<char> tData(new char[bufferSize]);

        m_QueueStructure[queueElems].data = tData;

        m_QueueStructure[queueElems].inUse  = true;

        m_QueueStructure[queueElems].compressedLength = _compressedLength;

        m_QueueStructure[queueElems].uncompressedLength = _uncompressedLength;

        m_QueueStructure[queueElems].packetType         = _packetType;

        m_CurrentElementsOfQueue++;

        return queueElems;
    }

    Data& GetElement(int index)
    {
        Data& DataElement = m_QueueStructure[index];

        return DataElement;
    }

    void ClearElementIndex(Data& delValue)
    {
        m_CurrentElementsOfQueue--;

        delValue.inUse = false;
    }

};
4

2 回答 2

0

for(queueElems = 0; queueElems < MAX_QUEUE_ELEMENTS; queueElems++)循环后queueElems的值为 32,但m_QueueStructure只有 32 个元素,因此您尝试访问m_QueueStructure[queueElems].data第 33 个元素。那个问题。

编辑:尝试使用m_QueueStructure[queueElems].data.reset(new char[bufferSize]);

于 2012-05-09T09:23:30.807 回答
0

解决了这个问题。我做了两个改变。在 wait_and_pop 函数中,我返回的是索引而不是 Data&。当我返回 Data& 时,这解决了分配问题。由于 shared_array.get() 的 memset 发生了另一次崩溃。吸取的教训,永远不要 memset 一个 shared_array 或一个 shared_ptr。

于 2012-05-10T01:20:41.593 回答