您的位置:首页 > 其它

关于strcpy与memcpy函数的地址重叠问题

2017-08-01 15:28 246 查看
大家一般认为名不见经传strcpy函数实现不是很难,流行的strcpy函数写法是:

[cpp] view
plaincopy

char *my_strcpy(char *dst,const char *src)  

{  

    assert(dst != NULL);  

    assert(src != NULL);  

    char *ret = dst;  

    while((* dst++ = * src++) != '\0')   

        ;  

    return ret;  

}  

如果注意到:

1,检查指针有效性;

2,返回目的指针des;

3,源字符串的末尾 '\0' 需要拷贝。

写出上面实现函数就不在话下。

然而这样的实现没有考虑拷贝时内存重叠的情况,下面的测试用例就能使调用my_strcp函数的程序崩溃:

[cpp] view
plaincopy

char str[10]="abc";  

my_strcpy(str+1,str);  

然而调用系统的strcpy函数程序正常运行,打印str结果为“aabc”!可见系统strcpy函数的实现不是这样的。

strcpy的正确实现应为:

[cpp] view
plaincopy

char *my_strcpy(char *dst,const char *src)  

{  

    assert(dst != NULL);  

    assert(src != NULL);  

    char *ret = dst;  

    memcpy(dst,src,strlen(src)+1);  

    return ret;  

}  

memcpy函数实现时考虑到了内存重叠的情况,可以完成指定大小的内存拷贝,它的实现方式建议查看文章“卓越的教练是如何训练高手的?”,会获益良多,这里仅粘帖函数memcpy函数的实现:

[cpp] view
plaincopy

void * my_memcpy(void *dst,const void *src,unsigned int count)  

{  

     assert(dst);  

     assert(src);  

     void * ret = dst;  

     if (dst <= src || (char *)dst >= ((char *)src + count))//源地址和目的地址不重叠,低字节向高字节拷贝  

     {  

         while(count--)  

         {  

             *(char *)dst = *(char *)src;  

             dst = (char *)dst + 1;  

             src = (char *)src + 1;  

         }  

     }  

     else                       //源地址和目的地址重叠,高字节向低字节拷贝  

     {   

         dst = (char *)dst + count - 1;  

         src = (char *)src + count - 1;   

         while(count--)   

         {  

             *(char *)dst = *(char *)src;  

             dst = (char *)dst - 1;  

             src = (char *)src - 1;  

         }  

    }  

    return ret;  

}  

两者结合才是strcpy函数的真正实现吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: