移动指针并重新分配,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()
因为你没有改变缓冲区的大小,想想吧。
如果你这样做
field += 4;
现在您丢失了对 field
开头的引用,因此您甚至不能对其调用 free
,当然也不能调用 realloc()
。例如阅读 WhozCraig 评论。
为相同尺寸做 realloc()
没有多大意义。
按照您的方式使用 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()
返回的相同指针传递给它,而不偏移它!
我正在尝试为输入文件编写缓冲区。 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()
因为你没有改变缓冲区的大小,想想吧。
如果你这样做
field += 4;
现在您丢失了对
field
开头的引用,因此您甚至不能对其调用free
,当然也不能调用realloc()
。例如阅读 WhozCraig 评论。为相同尺寸做
realloc()
没有多大意义。按照您的方式使用
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()
返回的相同指针传递给它,而不偏移它!