在C和C++编程中,memcpy
和 memmove
是两个用于内存操作的重要函数。它们虽然都用于将数据从一个内存区域复制到另一个内存区域,但在某些方面有着许多差异。因此本文将介绍这两个函数的工作原理、用途和差异。若是有错误请指出。
目录
memcpy 函数
工作原理
memcpy
函数是C和C++标准库中的一员,它的主要功能是将指定数量的字节从一个内存位置复制到另一个内存位置。它以字节为单位进行复制,通常以以下方式调用:
void* memcpy(void* dest, const void* src, size_t n);
dest
:目标内存区域的指针,数据将被复制到这个地址。
src
:源内存区域的指针,数据将从这个地址复制出来。
n
:要复制的字节数。
实现原理
memcpy
通常会以字节为单位进行拷贝。它会从源内存地址开始,依次将每个字节的数据复制到目标内存地址。这个过程会持续直到复制了指定数量的字节或直到遇到特定的终止条件。
模拟函数
void* my_memcpy(void* dest, const void* src, size_t sz) {
assert(dest && src);
while (sz--) {
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
memmove 函数
工作原理
memmove
函数与 memcpy
类似,也用于将数据从一个内存位置复制到另一个内存位置,但它在处理重叠内存区域时有所不同。memmove
的函数签名如下:
void* memmove(void* dest, const void* src, size_t n);
memmove
会处理源和目标内存区域的重叠情况,以确保复制的数据不会受到影响。它会根据需要选择正确的复制策略,可能以较慢的方式执行复制,以保证数据的完整性。
实现原理
-
判断重叠情况:
memmove
首先会判断源内存区域和目标内存区域是否重叠。这可以通过比较源地址和目标地址以及数据的长度来完成。如果发现重叠,就需要采取一些额外的步骤来确保数据不会被破坏。 -
选择复制策略: 一旦确定了重叠情况,
memmove
会选择合适的复制策略。通常,它会根据重叠的情况选择以下两种策略之一:-
从前向后复制: 如果源内存区域在目标内存区域之前,
memmove
会从前向后复制数据。这意味着它会从源内存的起始位置开始复制数据,逐个字节或字节块地复制数据到目标内存区域。这确保了在复制过程中不会覆盖尚未复制的数据。 -
从后向前复制: 如果源内存区域在目标内存区域之后,
memmove
会从后向前复制数据。这意味着它会从源内存的末尾位置开始复制数据,逐个字节或字节块地复制数据到目标内存区域。这同样确保了在复制过程中不会覆盖尚未复制的数据。
-
-
执行复制: 一旦选择了适当的复制策略,
memmove
会开始执行数据复制操作。它会按照所选的方向逐个字节或字节块地复制数据,直到复制了指定数量的字节或直到达到复制结束的条件。 -
完成复制: 当数据复制完成时,
memmove
函数就会返回目标内存区域的指针,表明复制已经成功完成。
模拟函数
void my_memmove(void* dest, const void* src, size_t sz) {
if (dest < src) {
int i = 0;
for (i = 0; i < sz; i++) {
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else {
while (sz--) {
*((char*)dest + sz) = *((char*)src + sz);
}
}
}