最近我参加了一次工作面试,被要求实现循环缓冲区类。要求不使用任何容器(包括STL)。
我的代码如下:
template<class T>
class CircularFifo
{
T * _data;
size_t _size;
size_t _read; // last readen elem
size_t _write; // next write index
CircularFifo(CircularFifo const &) = delete;
CircularFifo & operator=(CircularFifo const &) = delete;
CircularFifo(CircularFifo &&) = delete;
CircularFifo & operator=(CircularFifo &&) = delete;
public:
explicit inline
CircularFifo(size_t size = 2048)
: _data(new T[size])
, _size(size)
, _read(-1)
, _write(0)
{
if (0 == _size)
{
throw std::runtime_error("too empty buffer");
}
if (1 == _size)
{
throw std::runtime_error("too short buffer");
}
if (-1 == size)
{
throw std::runtime_error("too huge buffer");
}
}
inline ~CircularFifo()
{
delete []_data;
}
inline T read()
{
if (_read == _write)
{
throw std::runtime_error("buffer underflow");
}
return _data[(++_read) % _size];
}
inline void write(T const & obj)
{
if (_read == _write)
{
throw std::runtime_error("buffer overflow");
}
_data[(_write++) % _size] = obj;
}
};
面试官表示代码风格很好,但缓冲区中存在一个错误,这将使该类不可靠。她要求我找到它,但我完全失败了。她也没有向我透露这个错误。
我重新检查了一切:泄漏、算术、可能的溢出等等。我的头几乎要爆炸了。我不知道哪里出错了。请帮帮我。
P.S. 对于我的混乱英语,我感到抱歉。
read
函数中,您需要检查_read
不等于_write
,然后在使用_read
之前对其进行预增。这对我来说似乎有点可疑。 - Colininline
的。(这不是一个错误,只是一个小的可读性问题,在面试中可能会让你看起来不太好。) - nwpif (-1 == size)
无法涵盖所有溢出情况。 - wkl