我试图创建一个文本文件的精确副本,我正在使用循环缓冲区。
我使用的写入方法是:
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.
}
}
以下是我将每个char复制到缓冲区的方法:
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.
答案 0 :(得分:1)
显示初始化代码后,问题很明显:您在设置之前使用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->size
之前设置cBuff->cBuffItems
);这也有效(只要你使分配大小与记录的大小一致。
你应该可以检查calloc()
的结果。