1.strcpy函数
详细参考:http://www.cnblogs.com/chenyg32/p/3739564.html
详细参考:http://blog.chinaunix.net/uid-26495963-id-3080058.html
已知strcpy函数的原型是:
char *strcpy(char *dst, const char *src); 实现strcpy函数 解释为什么要返回char * 假如考虑dst和src内存重叠的情况,strcpy该怎么实现
2.strcpy函数的形式
char *strcpy(char *strDest, const char *strSrc) { assert((strDest!=NULL) && (strSrc !=NULL)); char *address = strDest; while( (*strDest++ = * strSrc++) != '\0') return address ; }
3.memcpy函数的微软实现
void * __cdecl memcpy (void * dst,const void * src, size_t count ) { void * ret = dst; #if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) { extern void RtlMoveMemory( void *, const void *, size_t count ); RtlMoveMemory( dst, src, count ); } #else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */ /* * copy from lower addresses to higher addresses */ while (count--) { *(char *)dst = *(char *)src; dst = (char *)dst + 1; src = (char *)src + 1; } #endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */ return(ret); }
4.memmove函数用法和实现
void *memmove(void *dest, const void *source, size_t count) { assert((NULL != dest) && (NULL != source)); char *tmp_source, *tmp_dest; tmp_source = (char *)source; tmp_dest = (char *)dest; if(tmp_source<=tmp_dest&&tmp_source+count>=tmp_dest) { tmp_source += count - 1; tmp_dest += count - 1; while(count--) *tmp_dest-- = *tmp_source--; } else { while (count--) { *tmp_dest++=*tmp_source++; } } return tmp_dest; }
4. 举例解释上边几个函数的不同
dst>=src
src+cnt>=dst
第一种情况下,拷贝重叠的区域不会出现问题,内容均可以正确的被拷贝。
第二种情况下,问题出现在右边的两个字节,这两个字节的原来的内容首先就被覆盖了,而且没有保存。所以接下来拷贝的时候,拷贝的是已经被覆盖的内容,显然这是有问题的。
举例
#include <iostream> #include <stdio.h> int main(void) { char s[]="123456789"; char d[]="123"; strcpy(d,s); printf("%s,\n%s",d,s); return 0 }
key :以上程序的结果为:123456789,56789
cause:至于原因,应该是当初分配的内存地址是连续内存的问题,原来是1234\0123456789\0,strcpy后变成了123456789\06789\0