当前位置: 首页 > 编程日记 > 正文

c语言实现memcpy

今天到I 公司去面试,面试方式比较特殊,没有笔试,就是2 个面试官,一人一句轮番发问,涉及面很广,涉及到操作系统(MMUpage outprocess/threadsemaphoreinterrupt), OOP( 多态、design pattern) 、数据结构( 排序、二叉查找树) 、计算机网络(OSI 5)C 语言(big/small endian) 、英语口语等等,问了大约一个小时左右。

所有问题都是口头表述,只在纸上写了一个memcpy 程序,用C 语言实现,脑子一发蒙,既然写成了strcpy ,真该死。

回家了查询了一下memcpy 定义,如下:

Void *memcpy(void *dest, const void *src, unsigned int count);

查询msdn, 发现Remark 如下:

memcpy copies count bytes from src to dest ; If the source and destination overlap, the behavior of memcpy is undefined. Use memmove to handle overlapping regions.

以上描述针对dest src 所指的内存地址有重叠的情况,内存地址重叠情况,memcpy 函数处理步骤未定,而memmove 对重叠情况给予处理;

winXP+visual c++2005 测试 memcpy 函数,程序如下:

 

#include "stdafx.h"

#include <string.h>

int _tmain (int argc , _TCHAR * argv [])

{

       char s [16] = "aabbcc" ;

       char d [16] = {0};

      

       memcpy (s +2, s , 4);

       printf ("%s" , s );

       return 0;

}

结果输出 “aaaabb”, 由此可见windows 平台的c 运行时MSVCRTmemcpy 函数对重叠部分做了处理,同memmove 的实现。//notes: 如果重叠部分不做处理,应该输出”aaaaaa”

下面我们用c 语言来实现memcpy 函数, 首先我们写出不对内存重叠的处理函数,如下:

void *memcpy_no_handle_overlap (void *dest , void *src , unsigned int count )

{

       if ((NULL ==dest ) || (NULL ==src ))

              return NULL ;

 

       char *d = (char *)dest ;

       char *s = (char *)src ;

 

       //Do normal (Upwards) Copy

       while (count -- > 0)

              *d ++ = *s ++;

       return dest ;

}

测试程序如下:

int _tmain(int argc, _TCHAR* argv[])

{

       char s[16] = "aabbcc";

       char d[16] = {0};

      

       memcpy_no_handle_overlap(s+2, s, 4);

 

       printf("%s", s);

       return 0;

}

输出结果”aaaaaa”

下面讨论处理memory overlapping 情况,如下图:




判断overlapping 条件如下:

If ( (dest <= src) ||                // green region 1

   (dest >=src+count) )           // green region 2

{

       // no memory overlapping

}

Else  // red region 3

{

       // there is overlapping

}

Overlapping 的处理:

我们可以看到memcpy_no_handle_overlap 函数,是从低地址依次赋值到高地址;在处理overlapping 时,如果我们采用同样的方法( 低地址到高地址) ,高地址的值将会被覆盖,所以我们应该从高地址依次到低地址赋值,如下图:

 

  函数代码如下:

void *memcpy_handle_overlap(void *dest, void *src, unsigned int count)

{

       if ((NULL==dest) || (NULL==src))

              return NULL;

 

       char *d = (char *)dest;

       char *s = (char *)src;

 

       //Check for overlapping buffers:

       if ( (d<=s) || (d>=s+count) )

       {     

              //Do normal (Upwards) Copy

              while (count-- > 0)

                     *d++ = *s++;

       }

       else

       {

              //Do Downwards Copy to avoid propagation

              while (count > 0)

              {

                     *(d+count-1) = *(s+count-1);

                     --count;

              }

 

       }

 

       return dest;

}

测试代码:

int _tmain(int argc, _TCHAR* argv[])

{

       char s[16] = "aabbcc";

       char d[16] = {0};

      

       memcpy_handle_overlap(s+2, s, 4);

 

       printf("%s", s);

       return 0;

}

输出结果为: aaaabb

 

最后测试代码如下:

int _tmain(int argc, _TCHAR* argv[])

{

       char s[16] = "aabbcc";

       memcpy_no_handle_overlap(s+2, s, 4);

       printf("memcpy(ignore memory overlapping): %s/n", s);

 

       strcpy(s, "aabbcc");

       memcpy_handle_overlap(s+2, s, 4);

       printf("memcpy(handle memory overlapping): %s/n", s);

 

     strcpy(s, "aabbcc");

       memcpy(s+2, s, 4);

       printf("memcpy( MSVCRT ): %s/n", s);

 

       strcpy(s, "aabbcc");

       memmove(s+2, s, 4);

       printf("memmove( MSVCRT): %s/n", s);

 

       return 0;

}

输出结果为:

memcpy(ignore memory overlapping): aaaaaa

memcpy(handle memory overlapping): aaaabb

memcpy( MSVCRT ): aaaabb

memmove( MSVCRT): aaaabb

相关文章:

Java项目:图书管理系统(java+swing+Gui+Mysql)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 功能介绍&#xff1a;借阅列表、图书类别管理、图书馆里、用户管理、借阅管理、关于我们 登录服务类&#xff1a; WebServlet("/LoginServlet") public class LoginServlet extends HttpServlet …

十五天精通WCF——第三天 client如何知道server提供的功能清单

通常我们去大保健的时候&#xff0c;都会找姑娘问一下这里能提供什么服务&#xff0c;什么价格&#xff0c;这时候可能姑娘会跟你口述一些服务或者提供一份服务清单&#xff0c;这样的话大 家就可以做到童嫂无欺&#xff0c;这样一份活生生的例子&#xff0c;在wcf中同样是一个…

MySQL Cluster 日常维护

在前面几篇文章已经详细介绍了MySQL Cluster的搭建&#xff0c;配置讲解。而且相信大家都掌握了基本用法。现在我们来看看Cluster的日常维护。熟悉日常维护&#xff0c;将有助于工作中更好的管理和使用Cluster。 一. 数据备份 相信大家都熟悉mysql的日常备份工具&#xff0c;比…

20165219王彦博《基于Cortex-M4的虚拟机制作与测试》课程设计个人报告

20165219王彦博《基于Cortex-M4的虚拟机制作与测试》课程设计个人报告 一、个人贡献 参与课设题目讨论及完成全过程&#xff1b; 资料收集&#xff1b; 负责环境搭建&#xff0c;代码运行下载&#xff1b; 撰写小组结题报告。 二、设计中遇到的问题及解决方法 1 实验六以太网服…

extern数组与extern指针

数组名代表了存放该数组的那块内存&#xff0c;它是这块内存的首地址。这就说明了数组名 是一个地址&#xff0c;而且&#xff0c;还是一个不可修改的常量&#xff0c;完整地说&#xff0c;就是一个地址常量。数组名 跟枚举常量一样&#xff0c;都属于符号常量。数组名 这个符号…

Java项目:医院管理系统(java+javaweb+jdbc+Mysql+lw)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 功能介绍&#xff1a; 登录、注册、用户/管理员(角色)、用户信息管理、科系信息管理、查看所有科系、新增科系信息、删除指定科系、修改科系信息、病房信息管理、病人信息管理、医生类型管理、病人手术管理…

Mongodb地理空间索引

1、索引&#xff1a; 建立索引既耗时也费力&#xff0c;还需要消耗很多资源。使用{"bakckground":true}选项可以使这个过程在后台完成&#xff0c;同时正常处理请求。如果不包括background 这个选项&#xff0c;数据库会阻塞建立索引期间的所有请求。阻塞的做法会让索…

Juniper的路由器、防火墙、交换机如何恢复出厂配置

Juniper的路由器、防火墙、交换机如何恢复出厂配置有些时候&#xff0c;在正常的业务使用中&#xff0c;逐条删除配置的内容很繁琐&#xff0c;我们可以使用恢复出厂配置&#xff0c;清空设备中的配置&#xff1b;还有的时候&#xff0c;由于设备配置异常&#xff0c;可以使用恢…

【转载】标准输入输出、错误输出、重定向标准输出

【转载】标准输入输出、错误输出、重定向标准输出 原文&#xff1a;标准输入输出、错误输出、重定向标准输出 再来看看 >& 操作符&#xff1a; 重定向操作符描述 > 将命令输出写入到文件或设备&#xff08;如打印机&#xff09;&#xff0c;而不是命令提示符窗口或…

(Interrupt Latency) 中断延迟

中断延迟 (Interrupt Latency) 中断延迟 是指从硬件中断发生到开始执行中断处理程序第一条指令之间的这段时间。 也就是&#xff1a; 计算机接收到中断信号到操作系统作出响应&#xff0c;并完成换到转入中断服务程序的时间。 不严格地&#xff0c;也可以表述为&#xff1a…

Java项目:干活管理系统(java+SSM+Jsp+Mysql)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 前台用户和后台管理员两种角色&#xff1a; 前台用户功能有&#xff1a;发布兼职、发布帖子、查看公告、个人中心、投诉等。 后台管理员功能有&#xff1a;用户管理、兼职管理、帖子管理、聊天管理、广告管…

20135234mqy 实验四

北京电子科技学院&#xff08;BESTI&#xff09; 实 验 报 告 课程&#xff1a;java程序设计 班级&#xff1a;1352 姓名&#xff1a;mqy 学号&#xff1a;20135234 成绩&#xff1a; 指导教师&#xff1a;娄嘉鹏 实验日期&#xff1a;2015.6…

我的第一张地图报表

一直以来对于地图都很陌生&#xff0c;感觉好强大&#xff0c;可以根据地理位置去分析数据&#xff0c;下面我简单的做了一张地图展示数据的报表。 接下来就简单的说一下设计过程和应该注意的地方 效果&#xff1a;&#xff08;鼠标放在省份区域上&#xff0c;显示该省的数据&a…

SpringBoot第十篇:thymeleaf详解

作者&#xff1a;追梦1819 原文&#xff1a;https://www.cnblogs.com/yanfei1819/p/10931435.html 版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请附上博文链接&#xff01; 引言 SpringBoot 对 Web 的支持&#xff0c;官方推荐的是模板引擎 thymelaf。本章中&…

嵌入式系统开发过程中遇到的——volatile

嵌入式 系统开发过程中遇到的—— volatile 对于不同的计算机体系结构&#xff0c;设备可能是端口映射&#xff0c;也可能是内存映射的 。如果系统结构支持独立的 I/O 地址空间&#xff0c;并且是端口映射&#xff0c;就必须使用汇编语言完成实际对设备的控制&#xff…

薏米红豆粥的功效和实践演示

熬薏米红豆粥有很多技巧和讲究。薏米很硬&#xff0c;红豆也很硬&#xff0c;假设已经煮在锅里&#xff0c;大概熬一个多小时不坏&#xff0c;这是一种浪费火灾或电力&#xff0c;它甚至可以把水烧开&#xff0c;原因症结。我建议的方法有两种&#xff1a;第一种方法是在锅里加…

Java项目:财务预算管理系统(java+SSM+Jsp+Mysql+Layui+Maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 功能包括&#xff1a;实现公司对项目的管理。 二、项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 mysql Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09; …

POJ 3080 多个串最长公共子序列

求多个串最长公共子序列&#xff0c;字典序最小输出。枚举剪枝kmp.比较简单&#xff0c;我用find直接查找16ms #include<iostream> #include<string> #include<algorithm> using namespace std; string s[61]; int main() {int ta;cin>>ta;int n;while…

HDU 2561 第二小整数

2019-05-27 18:07:06 加油&#xff0c;坚持&#xff01;&#xff01;&#xff01; 水题 #include <bits/stdc.h> using namespace std; int a[100]; int main() {int t;scanf("%d", &t);while(t--){int n;scanf("%d", &n);for (int i 0; i …

Java项目:在线高中考试系统(java+SSM+Jsp+Mysql+Maven)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 项目分为前台和后台&#xff0c;前台主要为学生角色、后台主要为管理员角色。 管理员添加试题和发布试卷&#xff0c;学生负责在线考试、在线查看成绩和错题记录列表等。 管理员功能有&#xff1a;年级管理…

asp.net mvc 学习

Routing讲解&#xff1a; http://www.cnblogs.com/wangiqngpei557/p/3379095.html Filter讲解&#xff1a; http://www.cnblogs.com/ymnets/p/3452407.html ASP.NET MVC 支持以下类型的操作筛选器&#xff1a; 授权筛选器。 这些筛选器用于实现 IAuthorizationFilter 和做出关于…

Linux数据库性能优化--文件系统相关优化

实际也中也用到下文中所说的内存文件系统1、ramfs 记得是32位文件系统安装oracle 为oracle分配SGA突破1.7G大小限制2、mmap 的文件可以放在tmpfs挂载的文件系统中http://www.ibm.com/developerworks/cn/linux/management/tune/index.html1&#xff0e; 引言实践证明Lin…

jQuery Mobile的学习时间bottonbutton的事件学习

版权声明&#xff1a;本文为博主原创文章。未经博主同意不得转载。https://blog.csdn.net/xmt1139057136/article/details/27700521 程序猿都非常懒&#xff0c;你懂的&#xff01; 生命的绝唱来机仅仅争朝夕&#xff0c;如诗的年华更需惜时如金。不要让今天的懈怠成为一生的痛…

C++中 public,protected, private 访问标号小结

第一&#xff1a;private, public, protected 访问标号的访问范围。 private&#xff1a; 只能由1.该类中的函数、2.其友元函数访问。 不能被任何其他访问&#xff0c;该类的对象也不能访问。 protected&#xff1a; 可以被1.该类中的函数、2.子类的函数、以及3.其友元函数…

Java项目:学生管理系统(java+Springboot+Maven+mybatis+Vue+Mysql)

源码获取&#xff1a;博客首页 "资源" 里下载&#xff01; 一、项目简述 本系统功能包括&#xff1a; 学生管理&#xff0c;教师管理&#xff0c;课程管理&#xff0c;成绩管理&#xff0c;系统管理等等。 二、项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 M…

UVA 11752 超级幂

UVA 11752 超级幂 Z - The Super PowersTime Limit:1000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Practice UVA 11752Description 题意&#xff1a;定义一个数为超级幂&#xff0c;当这个数能表示成至少两个不同数字的幂时。如162^4&#x…

Awstats

c是一个非常简洁而且强大的统计工具。它可以统计您站点的如下信息&#xff1a;一&#xff1a;访问量&#xff0c;访问次数&#xff0c;页面浏览量&#xff0c;点击数&#xff0c;数据流量等精确到每月、每日、每小时的数据二&#xff1a;访问者国家、访问者IP、操作系统、浏览器…

fixture详细介绍-作为参数传入,error和failed区别

前言 fixture是pytest的核心功能&#xff0c;也是亮点功能&#xff0c;熟练掌握fixture的使用方法&#xff0c;pytest用起来才会得心应手&#xff01; fixture简介 fixture的目的是提供一个固定基线&#xff0c;在该基线上测试可以可靠地和重复地执行。fixture提供了区别于传统…

哈佛结构和冯诺依曼结构区别。

哈佛结构是一种将程序指令存储和数据存储分开的存储器结构。中央处理器首先到程序指令存储器中读取程序指令内容&#xff0c;解码后得到数据地址&#xff0c;再到相应的数据存储 器中读取数据&#xff0c;并进行下一步的操作&#xff08;通常是执行&#xff09;。程序指令存储和…

js 数据函数

//shift&#xff1a;删除原数组第一项&#xff0c;并返回删除元素的值&#xff1b;如果数组为空则返回undefined var a [1,2,3,4,5]; var b a.shift(); //a&#xff1a;[2,3,4,5] b&#xff1a;1 //unshift&#xff1a;将参数添加到原数组开头&#xff0c;并返回数组的长度…