memcpy函数的作用:
将由src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内,函数返回一个指向dest的指针。

想必大多数人在面试时被要求写 memcpy的实现,很不幸,我也吃过这个亏(这种题要是写的一塌糊涂后面完全没戏),所以还是得提前准备一下,不然就只能呵呵了。

先来看看一段错误的示范: 找茬

void * memcpy(void *dest, const void *src, unsigned int count);
{
if ((src == NULL) || (dest == NULL))
return;

while (count--) *dest++ = *src++;

return dest;
}

特别说明:
1、与strcpy相比,memcpy遇到'\0'不会结束,而是一定要拷贝完n个字节,所以要指定拷贝的数据长度
2、memcpy可以拷贝任何数据类型的对象,如果dest和src的指针类型不一样,也需要处理,不能直接++使地址自增(例如: int* p和 char*q, p++指针的值是4个4个加(0,4,8),q++是1个1个加(0,1,2,3,4))
3、如果dest本身就有数据,执行memcpy()之后会覆盖原有的数据,所以src和dest所指向的内存区域不能有重叠
4、不能改变形参的值,定义新的临时变量来操作
5、参数提供的地址可能为空

完善后的代码:
void *memcpy(void *dest, const void *src, size_t count)
{
if (dest == NULL || src == NULL )
{
return NULL;
}

char *tmp_dest = dest;
const char *tmp_src = src;

while (count--) *tmp_dest++ = *tmp_src++ ;

return dest;
}

这样写的代码语法上看起来没什么问题了,但是不要忘记 src和dest所指向的内存区域不能有重叠,所以上面这段代码还是有bug。这个算是不容易看出来的bug,如果这样写了以后代码出现问题就很难排除了,这也就是为什么写不好这个函数指定会被淘汰的原因了。

dest和src所指向的地址有重叠的情况

内存地址重叠的情况分为两种,第一种是dest的地址在src地址的后面,另一种则是dest地址在src地址的前面。

这两种情况在memcpy中都是不允许出现的,需要在代码中处理以避免。
为了处理上面这两种情况,后来又提供了另一个函数memmove,在不需要保留原来内存区域的数据的时候可以使用memmove。

最终的正确的版本:

void *memcpy(void *dest, const void *src, size_t count)
{
if (dest == NULL || src == NULL || dest <= src+count)
{
return NULL;
}

char *tmp_dest = dest;
const char *tmp_src = src;

while (count--) *tmp_dest++ = *tmp_src++ ;

return dest;
}

上面就是正确的版本了,我所能考虑到的问题都处理了。

另外,这段代码还可以优化,比如根据CPU的字节长度,把原来一个一个字节拷贝转换为按CPU的长度拷贝,等等。
感兴趣的话自己研究一下吧,这里就不介绍了。

memcpy 函数实现相关推荐

  1. memcpy()函数

    1.memcpy()函数的实现 void *memcpy(void *dest, const void *src, size_t n); 从源src所指的内存地址的起始位置开始拷贝n个字节到目标des ...

  2. 最保险的函数间数组作为参数值传递与返回方法,用memcpy函数

    举例代码如下: void mycvCalcHist(IplImage *img,double out_hist[256]) {int i=0, j=0; double temp1=0;int temp ...

  3. 0.11内核rd_load@ramdisk.c中memcpy函数好像有bug

    0.11内核rd_load@ramdisk.c中memcpy函数好像有bug,如: #define memcpy(dst,src,n) \     __asm__("cld;rep;movs ...

  4. c语言内存拷贝 memcpy()函数

    需包含头文件:C 标准库 - <string.h> 文章目录 描述 声明 参数 返回值 实例1 实例2 实例3:覆盖原有部分数据 描述 C 库函数 void *memcpy(void *s ...

  5. c语言memcopy_C语言中memcpy 函数的用法详解

    C语言中memcpy 函数的用法详解 memcpy(内存拷贝函数) c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址 ...

  6. memcpy函数_[PART][BUG][MSVCRT][C][CCF NOI1097] 关于memcpy的坑

    [Incompleted] CCF NOI1097 试题,本人的源码: Ubuntu Pastebin​paste.ubuntu.com Ubuntu Pastebin Ubuntu Pastebin ...

  7. c语言中memcpy函数_带有示例的C中的memcpy()函数

    c语言中memcpy函数 memcpy()函数 (memcpy() function) memcpy() is a library function, which is declared in the ...

  8. C语言 memcpy函数(增加dst 从第一字节拷贝判断)的内部简单实现方式

    刚学习C语言编程的时候,感觉C内部函数深不可测,通过代码很难实现.后来经常慢慢的学习过程,理解了部分C函数的实现方法,下面简单说下memcpy函数的内部实现方式之一. 简单概括内存拷贝的含义:字节对齐 ...

  9. 让你提前认识软件开发(8):memset()与memcpy()函数

    第1部分 重新认识C语言 memset()与memcpy()函数 软件项目中的代码,少则数千行,多则上万行,但并非无规律可循.阅读了那么多代码之后,我发现有两个函数出现的频率很高,那就是memset( ...

  10. memcpy函数(多积累进大厂)

    作者:旧梦拾遗186 专栏:C语言编程----小比特成长日记 每日励志: 要想在人生中获胜,就要比别人更早地努力.而要及早努力,需要及早地为自己的人生做出规划,做好人生定位 前言: 今天小编带大家认识 ...

最新文章

  1. 1.磁盘的数据结构包括那些内容?
  2. XML DOM – 属性和方法概述
  3. 38页PPT深度解析:半导体设备产业链全景图
  4. live writer 51cto博客设置
  5. redis 数据完整性
  6. python time perf_Python Time 的学习笔记
  7. 精通ASP.NET MVC ——属性路由
  8. 高能同步辐射光源科学数据管理策略研究与应用
  9. Bootstrap 输入框组中控件的尺寸
  10. (98)Verilog HDL:流水灯设计
  11. 14-4 单任务版爬虫的架构
  12. Ubuntu下实现双屏独立切换
  13. PHP 运行 php-fpm 报错
  14. 软件工程基础-结对项目Ⅰ-2014
  15. 微信小程序组件slider
  16. php去除中文以外的特殊字符,php从文本中去除空格、特殊字符的4种情况
  17. java 获取真实ip地址
  18. 店宝宝:电商直播被“敲响警钟”了
  19. 「镁客·请讲」柏境数字张飞飞:做CG方向的VR视频,创造艺术和品质兼具的内容...
  20. [系统安全] 七.逆向分析之PE病毒原理、C++实现文件加解密及OllyDbg逆向

热门文章

  1. 我心中的坏男孩,愿你健康成长,早日闯出属于你自己的天地
  2. 数论概论读书笔记 2.勾股数组
  3. unable open file php,linux 使用lnmp 报Unable to open primary script
  4. 郫都区计算机老师周俊老师,成都郫都区亮灯“表白”教师 用一城绚烂映出桃李满天...
  5. aaron swartz_Aaron Osteraas如何使内容过渡到职业生涯
  6. 第一次加班-走在明亮寂寞的解放碑
  7. python扩展库导入方式_使用pip安装Python扩展库的方法
  8. 做好客户关系维护,你只需要一个CRM系统
  9. S-c crystal 组合
  10. JS-判断浏览器类型