方法一:
void * memmove_kk(void * dest,const void *src,size_t count)
{
char *tmp, *s;
/*如果目标地址小于源地址的话,从头开始拷贝*/
if (dest <= src)
{
char *tmp, *s;
/*如果目标地址小于源地址的话,从头开始拷贝*/
if (dest <= src)
{
tmp = (char *) dest;
s = (char *) src;
while (count--)
tmp = (char *) dest;
s = (char *) src;
while (count--)
{
*tmp++ = *s++;
*tmp++ = *s++;
}
}
/*如果目标地址大于源地址的话,从尾部往前拷贝,这样就避免了当内存重叠时导致拷贝出错*/
else
}
/*如果目标地址大于源地址的话,从尾部往前拷贝,这样就避免了当内存重叠时导致拷贝出错*/
else
{
tmp = (char *) dest + count;
s = (char *) src + count;
while (count--)
tmp = (char *) dest + count;
s = (char *) src + count;
while (count--)
{
*--tmp = *--s;
*--tmp = *--s;
}
}
return dest;
}
}
return dest;
}
方法二:
// 考虑重叠的状况
void* _memcpy(void* dest, void* src, int len)
{
if(!dest || !src || !len || dest == src)
return dest;
char* pdest = static_cast<char*>(dest);
char* psrc = static_cast<char*>(src);
// dest 在 src + len 范围内
if(pdest > psrc && pdest < (psrc + len))
{
// 先备份被覆盖部分
int need = psrc + len - pdest;
int offset = pdest - psrc;
char* pcache = new char[need];
int i = 0;
for (i = 0; i < need; ++i)
pcache[i] = psrc[offset + i];
// 拷贝起始部分
for (i = 0; i < offset; ++i)
pdest[i] = psrc[i];
// 拷贝剩余部分
for (i = 0; i < need; ++i)
pdest[offset + i] = pcache[i];
delete[] pcache;
}
else
{
for (int i = 0; i < len; ++i)
pdest[i] = psrc[i];
}
return dest;
}
void* _memcpy(void* dest, void* src, int len)
{
if(!dest || !src || !len || dest == src)
return dest;
char* pdest = static_cast<char*>(dest);
char* psrc = static_cast<char*>(src);
// dest 在 src + len 范围内
if(pdest > psrc && pdest < (psrc + len))
{
// 先备份被覆盖部分
int need = psrc + len - pdest;
int offset = pdest - psrc;
char* pcache = new char[need];
int i = 0;
for (i = 0; i < need; ++i)
pcache[i] = psrc[offset + i];
// 拷贝起始部分
for (i = 0; i < offset; ++i)
pdest[i] = psrc[i];
// 拷贝剩余部分
for (i = 0; i < need; ++i)
pdest[offset + i] = pcache[i];
delete[] pcache;
}
else
{
for (int i = 0; i < len; ++i)
pdest[i] = psrc[i];
}
return dest;
}
方法三:高效率内存拷贝(汇编)
在32
位的 x86 架构下的实现
global _fast_memcpy2
%define param esp+8+4
%define src param+0
%define dst param+4
%define len param+8
_fast_memcpy2:
push esi
push edi
mov esi, [src] ; source array
mov edi, [dst] ; destination array
mov ecx, [len]
shr ecx, 2 ; convert to DWORD count
rep movsd
pop edi
pop esi
ret
为了展示方便,这里假设源和目标内存块本身长度都是64字节的整数倍,并且已经4K页对齐。前者保证单条指令不会出现跨CACHE行访问的情况;后者保证测试速度时不会因为跨页操作影响测试结果。