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

C++ 循环缓冲区写入随机终止程序?,c++,circular-buffer,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"

“程序意外地完成了。”

我有一个类正在调用
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
}

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

if(firstInstance == 0){
m_posRead = 0;//only on first instance
m_posWrite = 0;//only on first instance
为什么只在第一个实例上初始化索引?其他实例将使这些成员未初始化,因此显然它们会损坏内存

编辑(关于评论):


好的,您可以使它们成为静态的,但是这暴露了您的设计中的一个严重问题。但这是离题的。在将它们设置为静态之后,另一个问题仍然存在:m_posWrite变量只递增,从不重置/递减-您如何期望它不会超出范围?

无论您提供了什么代码,似乎都是内存损坏的明显例子

首先

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

其次,在构造函数中,您正在执行

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

m_posWrite = (unsigned char)(m_posWrite + 1);
现在,这使得m_cMessageCB只有1字节宽。而在CMem::Write中,您正在做什么

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

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

这里m_posWrite已递增。它将首次写入第0个索引。下次调用CMem:Write时,它将尝试在第一个索引上写入,即“数组超出绑定写入”(因为m_cMessageCB只有1字节宽),并且它的行为未定义。它可能会在下一次写入或以后的任何其他写入时终止。

通常,如果在调试器中运行代码,当程序“意外完成”时,它会在出现问题的地方停止。是否没有人发布?您说这是一个循环队列,但何时结束?我只在调用CMem::write()时看到写入位置增加。您应该这样做:
if(m_posWrite==m_nBufferLength)m_posWrite=0您正在使用许多静态变量。我建议将它们改为成员变量。在某些情况下,静态变量会导致问题。例如,这些值对所有类都通用吗?还是仅仅是CMem的一个实例?如果是实例,则它们不应是静态的。@Trenin,当您定义一个类型a无符号字符,并且该值为255时,当您将其递增1时会发生什么?它返回到-1。。。然后您强制转换它,因为操作是作为整数完成的,现在-1变为0。我需要使它们也是静态的。。。但问题仍然没有解决我已经编辑了答案并回复了你的评论。让我知道它是否仍在崩溃。问题是我有多个线程调用这些方法转储数据以跨套接字写入。我使用的是静态的,所以线程之间的事情是一致的。分配给非静态地址的成员变量在每个线程中的此类的每个实例化上都会有所不同。“多线程”、“静态”。立即摆脱静态。@Martin James,我需要建立线程之间的关系,静态是唯一有效的方法。如果你有什么想法,请告诉我。