我对memcpy有疑问。我有一个缓冲区,想要将数据从缓冲区的后端移到前面。像这样:
int buffer[100];
memcpy(buffer, buffer + 10, 30);
存在重叠数据(元素11 - 21),是否会丢失数据或将数据复制到前端?这是一个好的做法"?
背景:我在微控制器上有一个很大的缓冲区,不想重新分配这个缓冲区。它是一个fifo缓冲区,每当有东西被读取时,后面的数据将被移到前面。我这样做是为了避免微控制器上的内存碎片。
答案 0 :(得分:2)
memcpy
的手册明确指出在缓冲区重叠时不使用它,在这种情况下你应该使用memmove
:
memcpy()函数将n个字节从内存区域src复制到内存区域dest。内存区域不得重叠。如果内存区域重叠,请使用memmove(3)。
为了完成起见,这里是memmove
:
memmove()函数将n个字节从内存区域src复制到内存区域dest。存储区可能重叠:复制的过程就好像src中的字节首先被复制到一个不与src重叠的临时数组中一样 或者dest,然后将字节从临时数组复制到dest。
答案 1 :(得分:1)
这是一个“好习惯”吗?
这是未定义的行为,所以不要这样做。
使用专门为此设计的memmove()
。
<强>描述强>
memmove()函数将n个字节从内存区域src复制到内存 区域目的地。存储区可能重叠:复制发生为 虽然src中的字节首先被复制到一个临时数组中 不与src或dest重叠,然后从中复制字节 临时数组到目的地。
以下段落摘自memcpy()的手册页,明确指出POSIX和C标准都是明确的,因为使用memcpy()
重叠的行为是udnefined领域
备注强>
未遵守内存区域要求 重叠一直是重大错误的根源。 ( POSIX和C. 使用带有重叠区域的 memcpy()的标准是明确的 产生未定义的行为。)最值得注意的是,在glibc 2.13中 某些平台上 memcpy()的性能优化(包括 x86-64)包括更改从中复制字节的顺序 src到dest。
答案 2 :(得分:1)
memcpy
是执行此任务的错误功能:
man memcpy , man memmove
#include <string.h> void *memcpy(void *dest, const void *src, size_t n); void *memmove(void *dest, const void *src, size_t n);
memcpy()
函数将n
个字节从内存区域src
复制到内存区域dest
。 内存区域不得重叠。如果内存区域重叠,请使用memmove(3)
。
memmove()
函数将n
个字节从内存区域src
复制到内存区域dest
。 内存区域可能会重叠:复制就像src
中的字节一样 首先复制到不与src
或dest
重叠的临时数组和字节 然后从临时数组复制到dest
。