memcpy函数相关问题

面试回来google了下才发现memcpy这题原来这么受面试官青睐!作为找工作的大四狗,我感觉自己水到家了。
今天去面试某公司,我投递的岗位的C/C++,面试官去吃饭了,让面Java的人来面试我,然后让我实现memcpy函数,并且写下了原形:
void memcpy(void dst,void src,int len)
当时我在考场上是如下写的。

void memcpy(void *dst,void *src,int len)
{
    if(dst==null||src==null)
        return;//楼主写到这里有疑问,函数原形是void,return应该不对
        
    while(len--)
    {
        *dst++=src++;
    }
}

面试官当时看了并且画了个图说没考虑内存重叠问题。
他当时画的是src指在dst后面,这种情况怎么可能内存重叠呢?实在想不明白,因为之前没看过这题,所以没什么把握不敢问。
还有我刚才搜了下,函数的原形应该是void memcpy(void dst,void *src,int len)
这个会不会是面试官故意考验我的呢?
刚在网上搜的memcpy函数的实现,为何一定要转换为(char *)

void *memcpy(void *dst,void *src,int len)
{
    if(dst==null||src==null)
        return null;
    void *ret=dst; 
    //没有内存重叠的情况
    if(src>dst||(char *)src+len<(char *)dst)
    {
        while(len--)
        {
            //如下书写形式优先级应该没错吧?
            *(char*)dst++=*(char *)src++;
            /*或者写成如下形式
              *(char*)dest = *(char*)src;
              dest = (char*)dest+1;
              src = (char*)src+1;
           */
        }
    }
    else//有内存重叠的情况,从后往前复制
    {
      src = (char *)src + len - 1;
      dst = (char *)dst + len - 1;
      while(len--)
      {
       *(char *)dst = *(char *)src;
       dst = (char *)dst - 1;
       src = (char *)src - 1;
       }
    }
    return ret;
  }

以上写了这么多,有问题欢迎指正,另外重申问题,为何要转换成char *呢?

阅读 4.5k
3 个回答
  1. C标准库中的函数原型是

void *memcpy(void *str1, const void *str2, size_t n);

参考地址:地址的2.14.4 章节

为什么一定要转换为(char *)

文档说的很清楚了

Copies n characters from str2 to str1. If str1 and str2 overlap the behavior is undefined.Returns the argument str1.

函数的返回值是void,但是这个函数操作之后,新的string的值应该是str1,也就是说,从str2所指的内存地址的起始位置开始拷贝n个字节到目标str1所指的内存地址的起始位置中,本质上是改变了str1指向的值.

所以,如果不是char *,你如何改变str1的值?

为什么没有重叠的判断条件是f(src>dst||(char *)src+len<(char *)dst)? 不是很明白,求详解。

面试官果然是C语言外行。memcpy(3)本来就不允许内存重叠,否则行为是undefined。当年adobe flash的一个BUG就是这个坑整出来的。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进