移动指针并重新分配,C

Move pointer and realloc, C

我正在尝试为输入文件编写缓冲区。 Buffer 应该总是包含定义数量的数据。如果使用了几个字节的数据,缓冲区应该从文件中读取数据,直到它再次具有定义的大小。

const int bufsize = 10;
int *field = malloc(bufsize*sizeof(int)); //allocate the amount of memory the buffer should contain
for(i=0;i<bufsize;++i) //initialize memory with something
    *(field+i) = i*2; 

field += 4; //Move pointer 4 units because the first 4 units were used and are no longer needed

field= realloc(field,bufsize*sizeof(int)); //resize the now smaller buffer to its original size
//...some more code were the new memory (field[6]-field[9]) are filled again...

这里是一个简短的例子,说明我目前是如何尝试这样做的(没有文件,因为这是不起作用的部分),但是 realloc() 总是 returns NULL。在此示例中,使用了前 4 个单元,因此指针应向前移动并分配内存末尾丢失的数据(以便它再次包含 10 个元素)。我做错了什么?

如果有人能帮助我,我将不胜感激

您需要 memmove() 而不是

memmove(field, field + 4, (bufsize - 4) * sizeof(*field));

你不需要realloc()因为你没有改变缓冲区的大小,想想吧。

  1. 如果你这样做

    field += 4;
    

    现在您丢失了对 field 开头的引用,因此您甚至不能对其调用 free,当然也不能调用 realloc()。例如阅读 WhozCraig 评论。

  2. 为相同尺寸做 realloc() 没有多大意义。

  3. 按照您的方式使用 realloc() 会导致一些其他问题,例如当它失败时您也会 运行 陷入同样的​​问题,您失去了对原始指针的引用。

    所以推荐的方法是

    void *pointer;
    pointer = realloc(oldPointer, oldSize + nonZeroNewSize);
    if (pointer == NULL)
        handleFailure_PerhapsFree_oldPointer();
    oldPointer = pointer;
    

所以你的问题的标题包含了它的答案,你需要的是将数据从偏移 4 * sizeof(int) 字节移动到指针的开头,memmove() 是完美的工具,请注意,您也可以考虑使用 memcpy(),但 memcpy() 无法处理重叠数据的情况,这就是您的情况。

您的问题应命名为循环缓冲区。

您应该在打开文件时只调用一次 malloc(),在关闭文件时调用一次 free()

您根本不需要调用 realloc()。所需要的只是按读取数据量提升指针,将其值包装在缓冲区大小周围,并用文件中的新数据替换旧数据。

你关于 realloc() 的问题:你必须将之前从 malloc()realloc() 返回的相同指针传递给它,而不偏移它!