bcopy correctly handles overlapping fields, while the behavior of memcpy is undefined if the source and destination overlap. The ANSI C memmove function must be used when the fields overlap.
在书里看到这两句话的时候挺困惑的,平时用这几个函数也没有留意这个问题,于是写了些代码验证了下这个问题。
#include <stdio.h>
#include <string.h>
void main()
{
int test[10];
int* source = test;
int* destination = &test[2];
int i = 0;
for (i = 0; i < 10; ++i)
{
test[i] = i;
}
memcpy(destination, source, sizeof(int) * 5); // 0 1 0 1 2 3 4 7 8 9
memcpy(source, destination, sizeof(int) * 5); // 2 3 4 5 6 5 6 7 8 9
bcopy(source, destination, sizeof(int) * 5); // 0 1 0 1 2 3 4 7 8 9
bcopy(destination, source, sizeof(int) * 5); // 2 3 4 5 6 5 6 7 8 9
memmove(destination, source, sizeof(int) * 5); // 0 1 0 1 2 3 4 7 8 9
memmove(source, destination, sizeof(int) * 5); // 2 3 4 5 6 5 6 7 8 9
for (i = 0; i < 10; ++i)
{
printf("%d ", test[i]);
}
printf("\n");
}
乍一看,三个函数的结果都是一样的。那为什么会有上面这两句话呢?于是在网上查了下别人的文章,终于理解了书里说的这两句话到底是什么意思,由于系统的原因,memcpy在这个系统的实现是对的,但是在其它系统上实现有可能就是不对的。
test | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
destination | 0 | 1 |
用memcpy对destination上第3个位置赋值的时候,由于test上第3个位置被之前赋值时修改为0,所以destination上的第3个位置有可能会被赋上0,内存重叠的问题就出现了。