移动指针和realloc,C

时间:2015-01-11 12:58:49

标签: c pointers realloc

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

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()总是返回NULL。在这个例子中,使用了前4个单元,因此指针应该向前移动,并且应该分配存储器末尾的缺失数据(以便它将再次包含10个元素)。我做错了什么?

如果有人能帮助我,我会非常感激

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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

您根本不需要致电realloc()。所有必要的是通过读取数据量来指示指针,将其值包围在缓冲区大小周围,并用文件中的新数据替换旧数据。

您对realloc()的问题:您必须将同一指针传递给malloc()realloc()之前返回的指针而不会抵消它!