Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为浮点值实现一个简单的环形缓冲区_C++ - Fatal编程技术网

C++ 为浮点值实现一个简单的环形缓冲区

C++ 为浮点值实现一个简单的环形缓冲区,c++,C++,我试图实现一个非常简单的环形缓冲区,用于以浮点值的形式保存音频样本流 我希望能够在任何时候拍摄音频输入的快照。我不需要弹出或删除任何值,只需保留最后n个样本的移动缓冲区 我想问一下,出于我的目的,这个实现是否存在任何潜在的问题 class RingBuffer { public: RingBuffer (int bufferSize) : bufferSize (bufferSize), count (0), head (0) { buffer = sta

我试图实现一个非常简单的环形缓冲区,用于以浮点值的形式保存音频样本流

我希望能够在任何时候拍摄音频输入的快照。我不需要弹出或删除任何值,只需保留最后n个样本的移动缓冲区

我想问一下,出于我的目的,这个实现是否存在任何潜在的问题

class RingBuffer
{
public:
    RingBuffer (int bufferSize) : bufferSize (bufferSize), count (0), head (0)
    {
        buffer     = static_cast<float *> (malloc(bufferSize * sizeof(float)));
        readBuffer = static_cast<float *> (malloc(bufferSize * sizeof(float)));
    }

    ~RingBuffer ()
    {
        if (buffer != nullptr) free(buffer);
        buffer = nullptr;

        if (readBuffer != nullptr) free(readBuffer);
        readBuffer = nullptr;
    }

    void push (float value)
    {

        if (count < bufferSize && head == 0)
        {
            buffer[count++] = value;
        }
        else if (count == bufferSize)
        {
            // reset head to beginning if reached the end
            if (head >= bufferSize)
            {
                head = 0;
                buffer[head] = value;
            }
            else
            {
                buffer[head++] = value;
            }
        }
    }

    /**
     * Return a snapshot of the buffer as a continous array
     */
    const float* getSnapshot () 
    {
         // Set up read buffer as continuous stream
         int writeIndex = 0;
         for (int i = head; i < count; ++i) 
         {
            readBuffer[writeIndex++] = buffer[i];   
         }
         for (int i = 0; i < head; ++i)
         {
             readBuffer[writeIndex++] = buffer[i];
         }
         return readBuffer;
    }

private:
    int bufferSize, head, count;
    float* buffer;
    float* readBuffer;
};
class-RingBuffer
{
公众:
RingBuffer(int bufferSize):bufferSize(bufferSize)、count(0)、head(0)
{
buffer=static_cast(malloc(bufferSize*sizeof(float));
readBuffer=static_cast(malloc(bufferSize*sizeof(float));
}
~RingBuffer()
{
如果(buffer!=nullptr)空闲(buffer);
缓冲区=空PTR;
如果(readBuffer!=nullptr)空闲(readBuffer);
readBuffer=nullptr;
}
无效推送(浮动值)
{
如果(计数<缓冲区大小和头==0)
{
缓冲区[计数++]=值;
}
else if(计数==缓冲区大小)
{
//如果到达终点,则将头部重置为起点
如果(磁头>=缓冲区大小)
{
水头=0;
缓冲区[头]=值;
}
其他的
{
缓冲区[head++]=值;
}
}
}
/**
*以连续数组的形式返回缓冲区的快照
*/
常量浮点*getSnapshot()
{
//将读取缓冲区设置为连续流
int writeIndex=0;
用于(int i=头;i<计数;++i)
{
readBuffer[writeIndex++]=缓冲区[i];
}
对于(int i=0;i
嗯,我确实看到了几个问题。对坏消息感到抱歉:-/

虫子

  • 这里有一个bug:
    buffer[head]=value。您不增加
    ,因此当下一个样本进入时,此位置的样本将丢失(覆盖)
  • 在构造函数中,您应该将
    buffer
    readBuffer
    初始化为
    nullptr
    :如果其中一个malloc失败,析构函数将尝试释放
  • getSnapshot
    中的第一个循环出现故障:终点应该是
    min(缓冲区大小、头部+计数)
    而不是
    count
设计问题

  • 正如mathematician1975所指出的,您应该为数组分配
    新的float[bufferSize]
    ,它比mallocs更简单、更可读
  • 您应该使用
    std::unique_ptr
    保存每个缓冲区,这样您就不再需要任何析构函数(并且您的代码会更安全)
  • 在处理循环缓冲区时,应使用模运算,例如
    writeIndex=(writeIndex+1)%bufferSize
    。这样您的代码会简单得多,尤其是在getSnapshot中(一个循环而不是两个循环)

这是一个偏离主题的问题,应该迁移到这是C++,你可以被说服使用<代码>新< /C>和<代码>删除<代码>代替<代码> Malc 和<代码>免费< /代码>没有坏消息。谢谢你详尽的回答。您发现的第一个bug应该是显而易见的(!),其余的bug提供了信息,帮助我更好地理解如何解决这个问题。