zoukankan      html  css  js  c++  java
  • 关于memcpy的实现

    今天去面试,面试官出了一个关于memcpy的函数原型的实现的问题,本来这个问题是很简单的,但是不知道当时怎么脑子一抽竟然写错了,真是”累觉不爱”了.感觉这份工作算是泡汤了,算了事情发生了,错过了也就错过了.既然这样就把这件事情记录下来,给自己提个醒~

    这个问题对于接触过的朋友自然不难,问题在于给自己一个分析的方法,遇到类似的问题怎么解决.

    memcpy实现内存拷贝,根据这个问题,我们可以提取出下面几点:

    1.可以拷贝任何数据,数据类型不能受限

    2.源数据不能被改变

    通过上面两点可以确定函数原型为void *memcpy(void *dest, const void *src),现在分析一下这些足够了吗?这个函数拷贝什么时候结束,当时我就用了这个函数原型,由于是拷贝的任意数据,所以不能指定一个明确的结束标志,既然这样那么只有明确的指定拷贝的大小才可以.所以函数原型变成这样void *memcpy(void *dest, void *src, size_t count);好吧,函数原型既然已经确认了,剩下的应该就是写函数了,先等等,先别急着写函数,实际上对于C语言的开发者来说,重要的不是函数功能的实现,重要的是函数出错时的处理,如果你用的是Java或者C#大不了抛个异常出来,软件崩溃一下,不会对其他造成任何影响;C这东西弄不好会把整个系统弄瘫痪,所谓”兵马未动,粮草先行”,我么还是先考虑考虑出错的问题吧!我们根据函数原型来分析,

    void *memcpy(void *dest, const void *src, size_t count);

    1.空指针的问题,如果dest、src两者或者两者之一为NULL,那么自然能没得完了;

    2.拷贝大小count为小于等于0的值,自然也是不正确的;

    3.目标有没有足够的大小容纳源数据,这个我们在函数内部似乎也无法进行保证,但是我们自己也要想到

    4.内存地址有没有重叠,这个我们暂时不考虑了。

    有了上面的提示写起来自然比较简单了

    #include <stdio.h>

    void *memcpy(void *dest, const void *src, size_t count)

    {

    if (NULL == dest || NULL == src || count <= 0)

    return NULL;

    while (count--)

    *dest++ = *src++;

    return dest;

    }

    上面这段代码在Linux中使用gcc编译是没错的,但是会有警告,所以改成这样:

    #include <stdio.h>

    void *memcpy(void *dest, const void *src, size_t count)

    {

    if (NULL == dest || NULL == src || count <= 0)

    return NULL;

    while (count--)

    *(char *)dest++ = *(char *)src++;

    return dest;

    }

    OK,也就这样了,要是面试官再问起内存重叠的问题,你再和他侃侃.

    我的面试算是泡汤了.

    总结:不要着急慢慢来,根据需求推出原型,根据原型推断问题,这算是个教训吧!!!

    补充:

    在这里非常感谢博客园的求道于盲  这位好心的网友指出了我程序中的两个错误,再次感谢.

    1.返回了一个++过的指针

    2.size_t是无符号类型的,size_t的定义为:typedef unsigned int size_t;

    所以count<=0,只会判断==0的情况,如果传入-1,会产生一个很大的无符号整型.

    希望别人注意,改过的程序如下:

    void *memcpy(void *dest, const void *src, int count)

    {

    void *ptr = dest;

    if (NULL == dest || NULL == src || count <= 0)

    return NULL;

     

    while (count--)

    *(char *)dest++ = *(char *)src++;

     

    return ptr;

    }

  • 相关阅读:
    es数据采集脚本样例
    实时文本采集器
    闭包理解
    django orm 联表查询优化
    关于vue中使用ajax页面不更新问题
    悲观锁和乐观锁的区别
    golang基础-tailf日志组件使用
    通过request获取不同方式请求的传参
    排序算法比对,插入算法和冒泡算法
    安利一波超级好课 —— 在家也不能闲着呀!!!
  • 原文地址:https://www.cnblogs.com/wangluojisuan/p/3471177.html
Copyright © 2011-2022 走看看