实现void *memcpy(void *to, const void *from, size_t count)
首先对这个函数做一些说明。
</pre></p><p>#include <string.h></p><p>void *memcpy(void *to, const void *from, size_t count)</p><p>函数memcpy()从from指向的数组向to指向的数组复制count个字符<span style="color:#FF0000;">。如果两数组重叠,不定义函数的行为</span>。</p><p>说明:1、from 和 to 所指的内存区域可能重叠,但是如果from 和 to 所指的内存区域重叠,那么这个函数并不能确保from所在重叠区域在拷贝之前不被覆盖。而使用memmove可以用来处理重叠区域。函数返回指向to 的指针。</p><p>在C99中,to和from由restrict修饰。</p><p>先来看看微软的实现:</p><p>void * __cdecl memcpy ( void * dst, const void * src, size_t count ){ void * ret = dst;</p><p>#if defined (_M_IA64) { extern void RtlMoveMemory( void *, const void *, size_t count );</p><p> RtlMoveMemory( dst, src, count ); }#else /* defined (_M_IA64) */ /* * copy from lower addresses to higher addresses */ while (count--) { *(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; }#endif /* defined (_M_IA64) */</p><p> return(ret);}</p><p>再来看看coreutils中的实现:</p><p>void *<strong class="cchl" id="m0"><span style="BACKGROUND-COLOR: #aaffff">memcpy</span></strong> (void *destaddr, void const *srcaddr, size_t len){ char *dest = destaddr; char const *src = srcaddr; while (len-- > 0) *dest++ = *src++; return destaddr;}</p><p>再来看Linux中实现:</p><p>void *memcpy(void *dest, const void *src, size_t count){ char *tmp = dest; const char *s = src;</p><p> while (count--) *tmp++ = *s++; return dest;}</p><p>根据这个问题,可以提取出下面几点:</p><p>1、可以拷贝任何数据,数据类型不能受限</p><p>2、源数据不能被改变</p><p>通过上面两点可以确定原型为 void *memcpy(void *dest, const void *src,size_t count ) ;</p><p>需要注意的问题:</p><p>a. 空指针的问题</p><p>b. 拷贝大小count为小于等于0的值;</p><p>c. 目标有没有足够的大小来容纳数据,这个我们在函数内部似乎也无法进行保证,但是我们自己要想到</p><p>d. 内存地址有没有重叠,这个暂时不考虑。</p><p>考虑到size_t 是无符号类型的,size_t 的定义为 typedef unsigned int size_t ;所以count <= 0实际上只会判断等于0的情况,因为传入count为负数会产生一个很大的无符号整型。</p><p>改过的程序如下:</p><p><pre name="code" class="cpp">void *memcpy(void *dest, const void *src, int count)
{
if (NULL == dest || NULL == src || count <= 0)
return NULL;
char *tmp = dest;
const char *s = src;
while (count--)
*tmp++ = *s++;
return dest;
}