循环缓冲区写入随机终止程序?

时间:2013-08-13 17:25:52

标签: c++ circular-buffer

"该程序意外结束。"

我有一个正在调用CMem::Write()的班级。它显示屏幕的迭代。有时它达到140,其他...... 12,3,42立即掉出来......非常随机 如果我删除对CMem::Write()的调用,程序将永远运行。

不确定为什么程序终止?我只能假设某些东西不是用CMem::Write()方法写的。

CMem::CMem()//sets up the "static" stack memory and the pointers to it; also the "static" positionIndex
{
    m_nBufferLength = sizeof(char); //short int
    static char *cMessageCB = new char[m_nBufferLength];
    static double *dTimeCB = new double[m_nBufferLength];

    m_cMessageCB = cMessageCB;
    m_dTimeCB = dTimeCB;


    ////////////////////////////////////////
    static char *cMessageReadList = new char[m_nBufferLength]; //max size can be the CB
    static double *dTimeReadList = new double[m_nBufferLength]; //max size can be the CB

    m_cMessageReadList = cMessageReadList;
    m_dTimeReadList = dTimeReadList;

    static int firstInstance = 0;

    if(firstInstance == 0){
        m_posRead = 0;//only on first instance
        m_posWrite = 0;//only on first instance

        firstInstance++;//check to see if multiple threads entered at the same time and look at the count
    }
}


void CMem::Write()
{//double dTime, char cMessage
//only one thread can write at a time... so lock... (make other threads with various random delays)

    static bool bUse = false;
    bool bDone = false;


    while(bDone == false){

        if(bUse == false){
            bUse = true;


            m_cMessageCB[m_posWrite] = m_cMessageWrite;
            m_dTimeCB[m_posWrite] = m_dTimeWrite;

            m_posWrite = (unsigned char)(m_posWrite + 1);


            static char cFlag = 0;
            //if writing position == reading position then flag
            if(m_posWrite == m_posRead){
                cFlag = 1;
            }

            bDone = true;
            bUse = false;
        }else if(bUse == true){
            printf("SUSPEND ");
        }
    }
}


void CMem::Read()
{//get the whole block of memory and increment the m_posRead accordingly
    unsigned char j = 0;

    while( (m_posRead + 1) != (m_posWrite + 1) ){
        m_cMessageReadList[j] = m_cMessageCB[m_posRead];//inc m_posRead at the end
        m_dTimeReadList[j] = m_dTimeCB[m_posRead];//inc m_posRead at the end

        m_posRead = (unsigned char)(m_posRead + 1);//circulate around
        j++;// 'j' is not circulating back around
    }

    //write to file
}

2 个答案:

答案 0 :(得分:0)

这些代码似乎是此代码的一个问题:

if(firstInstance == 0){
m_posRead = 0;//only on first instance
m_posWrite = 0;//only on first instance

为什么只在第一个实例上初始化索引?其他实例会使这些成员未初始化,因此显然会破坏内存。

编辑(关于评论):

好的,您可以将它们设置为静态,但这会显示您的设计存在严重问题。但这是偏离主题的。在使它们变为静态之后,另一个问题仍然存在:m_posWrite变量仅增加并且从不重置/减少 - 您如何期望它不会超出界限?

答案 1 :(得分:0)

使用您提供的任何代码,似乎是内存损坏的明显案例

第一

if(firstInstance == 0){
    m_posRead = 0;//only on first instance
    m_posWrite = 0;//only on first instance

    firstInstance++;//check to see if multiple threads entered at the same time and look at the count
}

上面的代码仅针对第一个实例将m_posRead和m_posWrite初始化为0。对于所有其他实例,它是未定义的。

其次,在你正在做的构造函数中

m_nBufferLength = sizeof(char); //short int
static char *cMessageCB = new char[m_nBufferLength];
m_cMessageCB = cMessageCB;

现在,这使得m_cMessageCB只有1个字节宽。而在CMem :: Write中你正在做

m_cMessageCB[m_posWrite] = m_cMessageWrite;
m_dTimeCB[m_posWrite] = m_dTimeWrite;

m_posWrite = (unsigned char)(m_posWrite + 1);

这里m_posWrite已递增。第一次它将写在第0个索引上。下次调用CMem:Write时,它将尝试在第一个索引上写入“Array Out Of Bound Write”(因为m_cMessageCB只有1个字节宽)并且它的行为是未定义的。它可以在下一次写入或任何其他未来写入时终止。