gpt4 book ai didi

C中的循环(ring)缓冲区写入方法

转载 作者:行者123 更新时间:2023-11-30 15:32:01 24 4
gpt4 key购买 nike

我正在尝试创建文本文件的精确副本,并且我正在使用循环缓冲区。

我使用的写入方法是:

void addItem(CircularBuffer *cBuff, BufferItem *cbItem) {
cBuff->cBuffItems[cBuff->lastInd] = *cbItem;
cBuff->lastInd = ( ((cBuff->lastInd) + 1) % cBuff->size);
if (cBuff->lastInd == cBuff->startInd)
{
cBuff->startInd = (cBuff->startInd + 1) % cBuff->size; // Overwriting full buffer.
}
}

这是我将每个字符复制到缓冲区的方法:

BufferItem result;
char ch;
while( ( ch = fgetc(fp) ) != EOF ){
result.offset = ftell(fp);
result.data = ch;
addItem(&cBuff, &result);
}

它只写前三个字符,然后给我一个段错误。我确保缓冲区大小足够大,我尝试了不同的数据集,所有数据集都给出相同的结果(仅将前 3 个字符复制到缓冲区中)。

如果我不将其添加到缓冲区,而只打印 result.offset 和 result.data,我会得到我所期望的结果。所以 addItem 一定是问题所在,如果我删除 addItem 中的第二行,它会起作用,但显然它只是覆盖了第一行。

我做错了什么?

编辑:

这里是循环缓冲区和循环缓冲区的实现:

// Circular buffer items.
typedef struct {
char data ;
off_t offset ;
} BufferItem ;

// Circular buffer
typedef struct {
int startInd; // Index of first element added to buffer.
int lastInd; // Index of most recent element added to buffer.
int size; // Number of elements in circular buffer.
BufferItem *cBuffItems; // Circular buffer items.
} CircularBuffer;

void initializeBuffer(CircularBuffer *cBuff, int size) {
cBuff->cBuffItems = calloc(cBuff->size, sizeof(BufferItem));
cBuff->size = size + 1;
cBuff->startInd = 0;
cBuff->lastInd = 0;
}

就像我提到的,我确实初始化了缓冲区,这是 main 的简化版本:

int main( int argc, char *argv[] )
{
if (argc != 4)
{
printf("Expected 3 arguments, received %d\n", argc - 1);
return 1;
}

int bufSize; // Capacity of BufferItems in circular buffer.
char *file; // Pathname of file to be copied.
char *copy; // Name to be given to the copy.

sscanf(argv[1], "%d", &bufSize);
file = argv[2];
copy = argv[3];

initializeBuffer(&cBuff, bufSize);

// Open file to be copied.
FILE *fp = fopen(file, "r" );

// Create copy file.
FILE *cp = fopen(copy, "w+" ); // Overwrite if file exists.

BufferItem result;
char ch;
while( ( ch = fgetc(fp) ) != EOF ){
result.offset = ftell(fp);
result.data = ch;
addItem(&cBuff, &result);
}

fclose(fp);
fclose(cp);

return 0;
}// Main.

最佳答案

一旦显示初始化代码,问题就清楚了:您在设置之前使用了cBuff->size

void initializeBuffer(CircularBuffer *cBuff, int size) {
cBuff->cBuffItems = calloc(cBuff->size, sizeof(BufferItem));
cBuff->size = size + 1;
cBuff->startInd = 0;
cBuff->lastInd = 0;
}

因此,您将使用准随机大小,并获得相应的准随机结果。正如您现在所看到的,正是您最初未显示的代码造成了麻烦 - 这就是为什么我们必须要求看到一个可行的示例!

你可以非常简单地修复它:

void initializeBuffer(CircularBuffer *cBuff, int size) {
cBuff->cBuffItems = calloc(size + 1, sizeof(BufferItem));
cBuff->size = size + 1;
cBuff->startInd = 0;
cBuff->lastInd = 0;
}

这使用参数size而不是cBuff的未初始化元素。我建议分配一定数量的元素,然后说有不同数量的元素可供使用,这会引起麻烦。我选择将两个数字加一;但总的来说,最好使用不带增量的 size 值。

您还可以重新排序分配(因此您可以在分配cBuff->cBuffItems之前设置cBuff->size);这也可以工作(只要您使分配大小与记录的大小一致。

可以说,您应该检查 calloc() 的结果。

关于C中的循环(ring)缓冲区写入方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24471949/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com