strcpy实现

常见strcpy实现  

  一个常见的strcpy实现如下:

 1 char *my_strcpy(char *dst, const char *src)
 2 {
 3     if (dst == nullptr || src == nullptr)    // 写成!dst或dst == 0都不推荐
 4         return nullptr;
 5 
 6     if (dst == src)                          // 判断dst和src是否已经指向同一块内存,若是则直接返回
 7         return dst;
 8 
 9     char *tmp = dst;
10     while ((*dst++ = *src++) != '\0')        // 注意在dst末尾加上'\0'
11         ;
12 
13     return tmp;                  // 在这里可能会不假思索就返回dst,但这样是有问题的,因为dst经过累加后实际已指向'\0'的下一块内存
14 }

  针对strcpy还有常见的一个问题就是:为什么要返回char *?

  因为要让strcpy支持链式赋值,例如:

strlen(strcpy(new char[20], src));

考虑内存重叠

   对于strcpy而言,该函数并没有考虑内存重叠的问题,例如

1 char s[10]="hello";
2 strcpy(s, s+1);    //应返回ello,
3 // strcpy(s+1, s); // 应返回hhello,但实际会报错,因为dst与src重叠了,把'\0'覆盖了

  所谓重叠,就是src未处理的部分已经被dst给覆盖了,只有一种情况:src<=dst<=src+strlen(src)。

  C函数memcpy自带内存重叠检测功能,下面给出memcpy的实现my_memcpy。

 1 char *my_memcpy(char *dst, const char *src, int cnt)
 2 {
 3     if (dst == nullptr || src == nullptr)
 4         return nullptr;
 5 
 6     char *tmp = dst;
 7     if (dst >= src && dst <= src + cnt - 1)    // 内存重叠,从高地址开始复制
 8     {
 9         dst = dst + cnt - 1;
10         src = src + cnt - 1;
11         while (cnt--)
12             *dst-- = *src--;
13     }
14     else                                       // 正常情况,从低地址开始复制
15     {
16         while (cnt--)
17             *dst++ = *src++;
18     }
19 
20     return tmp;
21 }
22 
23 char *my_strcpy(char *dst, const char *src)
24 {
25     if (dst == nullptr || src == nullptr)    // 写成!dst或dst == 0都不推荐
26         return nullptr;
27 
28     if (dst == src)                          // 判断dst和src是否已经指向同一块内存,若是则直接返回
29         return dst;
30 
31     char *tmp = dst;
32     my_memcpy(dst, src, strlen(src) + 1);  // 注意strlen并不会将‘\O’统计在内
33 
34     return tmp;
35 }

参考资料

  strcpy函数的实现

 

posted @ 2015-08-13 13:42  峰子_仰望阳光  阅读(451)  评论(0编辑  收藏  举报