移动数组中的数据会覆盖数据吗?

时间:2018-01-17 20:05:30

标签: c memcpy

我对memcpy有疑问。我有一个缓冲区,想要将数据从缓冲区的后端移到前面。像这样:

int buffer[100];
memcpy(buffer, buffer + 10, 30);

存在重叠数据(元素11 - 21),是否会丢失数据或将数据复制到前端?这是一个好的做法"?

背景:我在微控制器上有一个很大的缓冲区,不想重新分配这个缓冲区。它是一个fifo缓冲区,每当有东西被读取时,后面的数据将被移到前面。我这样做是为了避免微控制器上的内存碎片。

3 个答案:

答案 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中的字节一样   首先复制到不与srcdest重叠的临时数组和字节   然后从临时数组复制到dest