1.memcpy函数介绍
2.memmove函数介绍
一丶memcpy
void *
memcpy
(
void *
destination
,
const
void *
source
,
size_t
num
);
memcpy主要作用是用于拷贝不重叠的内存
其中destination是拷贝的目标空间, source是拷贝源 ,num是要拷贝的字节数
对于memcpy的模拟实现:
void* memcpy(void* dest , const void* arc , size_t sz)
{
assert( dest && arc ); //断言,确保两个指针都不为空
void * ret = dest;
while( sz-- )
{
*(char*)dest= *(char*)arc;
dest=(char*)dest+1;
arc=(char*)arc+1;
}
return ret ;
}
二丶memmove
void *
memmove
(
void *
destination
,
const
void *
source
,
size_t
num
);
memmove同样作为拷贝内存的函数,与memcpy的参数完全一样,两者的区别在于memmove的拷贝源和拷贝的目标空间可以重叠的内存。
因为拷贝的目标空间和拷贝源内存存在重叠的情况,因此在使用时我们需要考虑两种情况
即:
当拷贝源的起始地址小于拷贝空间的起始地址时:
正常的从前往后(低地址到高地址)开始拷贝,会出现前面目标空间的数据覆盖拷贝源的数据,导致最终得不到需要的结果。
此时就需要从高地址像地址值处(从后往前)开始拷贝
而当拷贝源的起始地址大于拷贝空间的起始地址时:
则应该正常的从前往后开始拷贝,此时若从后往前开始拷贝,依然会出现内存覆盖的问题
memmove的模拟实现:
void*memmove(void * dest , void* arc , size_t sz)
{
assert(dest && arc);
void* ret = dest;
//从前往后的情况
if(dest<arc)
{
while(sz--)
{
*(char*)dest = *(char*)arc;
dest = (char*)dest + 1;
arc = (char*)arc + 1;
}
}
//从后往前的情况
if(dest>arc)
{
while(sz--)
{
*((char*)dest + sz) = *((char*)arc + sz);
}
}
return ret ; //返回拷贝目标的起始地址
}
注:事实上,在vs2022环境下,memcpy也可以实现重叠内存的拷贝,但是变更环境后可能会出现问题,因此在重叠内存的拷贝时还是优先使用memmove , 并且memmove也可以实现不重叠内存的拷贝。