【问题标题】:Move pointer and realloc, C移动指针和重新分配,C
【发布时间】:2015-03-09 08:29:46
【问题描述】:

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

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 个元素)。我做错了什么?

如果有人可以帮助我,我将非常感激

【问题讨论】:

  • field += 4; //Move pointer 4 units because the first 4 units were used and are no longer needed 然后你怎么去free呢? “但 realloc() 总是返回 NULL”,这就是为什么你应该使用一个临时变量来free field 以防realloc 失败。
  • 您正在调用未定义的行为。您传递给realloc 的地址不是从malloccallocrealloc 返回的地址。您不能传递恰好在动态分配的缓冲区范围内某处的 any 地址。它必须是 非 NULL 地址直接从这些函数之一返回而无需修改。

标签: c pointers realloc


【解决方案1】:

你需要 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()无法处理重叠数据的情况,这是你的情况。

【讨论】:

  • 详细阐述:) '+1'
  • 非常感谢,很好的解释,我现在知道我的错误是什么
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-09
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    • 2021-04-03
    相关资源
    最近更新 更多