c-循环缓冲区实现中覆盖功能的尾部指针



我正在尝试实现一个用于记录消息的循环缓冲区。我已经实现了一个相当基本的解决方案,它似乎可以工作,但我对推送在实际情况下应该如何工作感到困惑。头部应该覆盖尾部吗?如果是,我们是否修改尾部以反映它指向下一个最旧的日志?

/******************************************************************************

Online C Compiler.
Code, Compile, Run and Debug C program online.

在这个编辑器中编写代码,然后按";运行";按钮编译并执行。

*******************************************************************************/

/******************************************************************************

Online C Compiler.
Code, Compile, Run and Debug C program online.

在这个编辑器中编写代码,然后按";运行";按钮编译并执行。

*******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdbool.h>
#include <string.h>
#define LOG_SIZE 10
typedef struct{
char *buffer[LOG_SIZE];
int16_t head;
int16_t tail;
int16_t count;
volatile bool full_status;
volatile bool empty_status;
}circbuff;
pthread_mutex_t circMutex;
void circbuff_reset(circbuff *circ_b)
{
circ_b->head = 0;
circ_b->tail =0;
circ_b->full_status =  false;
circ_b->count =0;
circ_b->empty_status =  false;
}
circbuff * circbuff_init ()
{
circbuff *my_circ_buff = (circbuff *) malloc(sizeof(circbuff));
circbuff_reset(my_circ_buff);
return (my_circ_buff);
}
void push(circbuff *circ_b, char* message)
{
pthread_mutex_lock(&circMutex);
if (!circ_b->full_status)
{
//circ_b->buffer[circ_b->head] =  (char*)malloc(strlen(message)+1);
circ_b->buffer[circ_b->head] = strdup(message);
//printf ("Value inserted at position %d is %s and count %drn", circ_b->head, circ_b->buffer[circ_b->head],circ_b->count);
circ_b->head = (circ_b->head + 1) % LOG_SIZE;
if(circ_b->head==circ_b->tail)
circ_b->full_status=true;
circ_b->empty_status=false;
circ_b->count++ ; 
}
else //can be changed to overwrite
{
free(circ_b->buffer[circ_b->head]);
circ_b->buffer[circ_b->head] = strdup(message);
//printf ("Value inserted at position %d is %s and count %drn", circ_b->head, circ_b->buffer[circ_b->head],circ_b->count);
circ_b->head = (circ_b->head + 1) % LOG_SIZE;
circ_b->tail = (circ_b->tail + 1) % LOG_SIZE;
if(circ_b->head==circ_b->tail)
circ_b->full_status=true;
circ_b->empty_status=false;

//printf("Cant push logsn");
}
pthread_mutex_unlock(&circMutex);
}
char* pop(circbuff *circ_b)
{
pthread_mutex_lock(&circMutex);
if (!circ_b->empty_status)
{
//printf ("Value read at position %d is %s and count %drn", circ_b->tail, circ_b->buffer[circ_b->tail],circ_b->count);
char* pop_value = circ_b->buffer[circ_b->tail]; //-->free after this? 

circ_b->tail = (circ_b->tail + 1) % LOG_SIZE;
if(circ_b->head==circ_b->tail)
circ_b->empty_status=true;
circ_b->count--;
circ_b->full_status=false;
return pop_value;
}
else
return "Empty Buffer";
pthread_mutex_unlock(&circMutex);
}

int main()
{
pthread_mutex_init(&circMutex,NULL);
circbuff* myBuffer = circbuff_init();
char buff[20];
scanf("%s", buff);
push(myBuffer, buff);
scanf("%s", buff);
push(myBuffer, buff);
char *tmp;
for(int i = 0 ;i < 2; i++)
{
tmp = pop(myBuffer);
printf("%s-poppedn",tmp);
free(tmp);
}
pthread_mutex_destroy(&circMutex);
}

这段代码非常糟糕。

circ_b->buffer[circ_b->head] = (char*)malloc(strlen(message)+1);
circ_b->buffer[circ_b->head] = message;

您似乎认为第二行会将消息复制到您刚刚修改过的空间中。它不会;你所做的只是泄露你刚刚分配的内存。您只需将malloc返回的指针替换为消息指针。

使用strdup,它将为您进行malloc和复制。

其次,当圆圈满了时,您需要释放旧节点的消息,并分配一个新节点。

你能在Linux桌面上运行这段代码吗?如果是这样的话,在Valgrind下运行它,它会揭露你所有的漏洞。

这些"挥发物"也毫无意义。

为了表明当前代码不起作用,我制作了一个不同的主

int main(){
circbuff* myBuffer = circbuff_init(10);
char buff[20];
scanf("%s", buff);
push(myBuffer, buff);
scanf("%s", buff);
push(myBuffer, buff);

for(int i = 0 ;i < 2; i++)
printf("%s-poppedn",pop(myBuffer));
}

运行它并获得

hello1
Value inserted at position 0 is hello1
hello2
Value inserted at position 1 is hello2
Value read at position 0 is hello2  <<<<======
hello2-popped
Value read at position 1 is hello2
hello2-popped

你看你两次打出了hello2

这是valgrims输出

==4752== HEAP SUMMARY:
==4752==     in use at exit: 94 bytes in 3 blocks
==4752==   total heap usage: 5 allocs, 2 frees, 2,142 bytes allocated
==4752==
==4752== 3 bytes in 1 blocks are definitely lost in loss record 1 of 3
==4752==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4752==    by 0x109282: push (in /home/pm100/ut/a.out)
==4752==    by 0x10971B: main (in /home/pm100/ut/a.out)
==4752==
==4752== 3 bytes in 1 blocks are definitely lost in loss record 2 of 3
==4752==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4752==    by 0x109282: push (in /home/pm100/ut/a.out)
==4752==    by 0x109746: main (in /home/pm100/ut/a.out)
==4752==
==4752== 88 bytes in 1 blocks are definitely lost in loss record 3 of 3
==4752==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4752==    by 0x109221: circbuff_init (in /home/pm100/ut/a.out)
==4752==    by 0x1096EC: main (in /home/pm100/ut/a.out)
==4752==
==4752== LEAK SUMMARY:
==4752==    definitely lost: 94 bytes in 3 blocks
==4752==    indirectly lost: 0 bytes in 0 blocks
==4752==      possibly lost: 0 bytes in 0 blocks
==4752==    still reachable: 0 bytes in 0 blocks
==4752==         suppressed: 0 bytes in 0 blocks
==4752==
==4752== For lists of detected and suppressed errors, rerun with: -s

相关内容

  • 没有找到相关文章

最新更新