我正在实现一个固定长度的缓冲区,分别使用尾部或头部指针读取或写入字符串。我有以下代码:
bool putBuffer(char *sMsz)
{
int iStrLen;
iStrLen = strlen(sMsz);
if(!iStrLen || iStrLen>MAX_LEN)
return 0;
while(iStrLen-->=0)
{
//if head crosses tail
if(iBufHead==iBufTail && iBufHead!=0 && dFlag)
{
while(cDebugBuf[iBufTail] != '\0')
{
iBufTail=iBufTail+1;
if (iBufTail>=CBUFF_SIZE)
iBufTail = 0;
}
iBufTail++;
}
if(iBufHead>=CBUFF_SIZE)
{
dFlag=1; // Used to know when buffer starts over writing prev data and meets tail on way
iBufHead = 0;
}
cDebugBuf[iBufHead++] = *(sMsz++);
}
return 1;
}
bool getBuffer(char *readData)
{
int i=0;
do
{
if(iBufTail==iBufHead)
return 0;
if(iBufTail>=CBUFF_SIZE)
iBufTail = 0;
readData[i++] = cDebugBuf[iBufTail++];
}while(cDebugBuf[iBufTail]!='\0');
iBufTail++;
return 1;
}
此代码一直有效,直到最大缓冲区被命中,当头指针再次启动时,尾指针未正确放置。
除了发现错误之外,还有任何改进代码的建议吗?
答案 0 :(得分:1)
使用循环缓冲区,至少有两种方法可以区分完整状态和空状态(head == tail
)。
允许缓冲区中的一个项目超出实际需要,并且在添加时不要让head
前进到tail
(而是提出“缓冲区已满”错误)。这样,head == tail
始终表示空。
保持“自由槽”变量以及头部和尾部,将其初始化为缓冲区的大小,在添加时递减,并在移除时递增。这样你可以通过设置为零来检测缓冲区已满,或者如果将缓冲区设置为原始大小则缓冲为空。
对于选项1,类似于:
def buffInit(sz):
global buffSz = sz
global buffData = alloc(buffSz+1) # allow for extra slot.
global buffHead = 0
global buffTail = 0
def buffAdd(item):
if (buffHead + 1) % buffSz == buffTail: # never fill extra slot.
return BUFFER_FULL
buffData[buffHead] = item
buffHead = (buffHead + 1) % buffSz
return OK
def buffGet():
if buffHead == buffTail:
return BUFFER_EMPTY
item = buffData[buffHead]
buffHead = (buffHead + 1) % buffSz
return item
对于选项2,类似于:
def buffInit(sz):
global buffSz = sz
global buffFree = buffSz # extra information.
global buffData = alloc(buffSz)
global buffHead = 0
global buffTail = 0
def buffAdd(item):
if buffFree == 0: # zero free slots means full.
return BUFFER_FULL
buffData[buffHead] = item
buffHead = (buffHead + 1) % buffSz
buffFree = buffFree - 1 # keep in sync.
return OK
def buffGet():
if buffFree == buffSz:
return BUFFER_EMPTY
item = buffData[buffHead]
buffHead = (buffHead + 1) % buffSz
buffFree = buffFree + 1 # keep in sync.
return item