关于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;
}
关于memcpy的实现的更多相关文章
- memcpy内存复制
memcpy(predata,frame,1920*1080*4);
- strcpy strlen memcpy等的函数实现
#include <assert.h> #include <string.h> #include <stdlib.h> #include <stdio.h&g ...
- memcpy函数用法
memcpy函数用法 .分类: VC++ VC++ mfc matlab 2011-12-01 19:17 14538人阅读 评论(0) 收藏 举报 null 原型:extern void *memc ...
- memcpy和memmove
memcpy函数 函数原型 void *memcpy(void *dest, const void *src, size_t n); dest:目标地址 src: 起始地址 n: 字节数 头文件 st ...
- strcpy和memcpy的区别(转载)
strcpy和memcpy都是标准C库函数,它们有下面的特点.strcpy提供了字符串的复制.即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符. 已知strcpy函 ...
- strncpy和memcpy的区别
今天不小心在该用memcpy的时候,用了strncpy使自己吃了亏,所以写出这个博文. memcpy就是纯字节拷贝,而strncpy就不同了,字符串是以'\0'结尾的.如果一个字符buffer长度为6 ...
- strcpy vs memcpy
[本文连接] http://www.cnblogs.com/hellogiser/p/strcpy_vs_memcpy.html [分析] strcpy和memcpy都是标准C库函数,它们有下面的特点 ...
- memcpy vs memmove
[本文连接] http://www.cnblogs.com/hellogiser/p/memcpy_vs_memmove.html [分析] memcpy与memmove的目的都是将N个字节的源内存地 ...
- SEH-关于捕获memcpy的异常
网上有说memcpy是C语言写的,没有异常处理机制. 但是貌似SEH可以处理. SEH("Structured Exception Handling"),即结构化异常处理·是(wi ...
- 等号赋值与memcpy的效率问题
转自:http://www.aiuxian.com/article/p-1309055.html 偶尔看到一个说法,说,小内存的拷贝,使用等号直接赋值比memcpy快得多.结合自己搜集到的资料,整理成 ...
随机推荐
- Nginx 基于客户端 IP 来开启/关闭认证
前些日子帮助公司在搭建了一个内部资源的导航页面,方便公司员工访问各种常用的系统.因为这个页面包含一些敏感信息,我们希望对其做认证,但仅当从外网访问的时候才开启,当从公司内网访问的时候,则无需输入账号密 ...
- LINQ-Group子句、Into子句及orderby子句
1. Group子句 LINQ表达式必须以from子句开头,以select或Group子句结束,所以除了使用select子句也可以使用Group子句来返回元素分组后的结果.Group子句用来查询结果分 ...
- final的作用
前言 一直想写写这个话题.代表公司也面试过一些求职者,每次面试我必问的两个问题之一 就是“请你谈一谈对于final关键字的理解”.这是一个简单的小问题,但是不要小看它,通过对这个问题的回答以及一些简单 ...
- Java基础(3)——变量
从这篇文章起开始正式进入正题啦,本文将较为简单的介绍一下变量以及常量.变量,顾名思义,就是可以变的量,常量那么久相反了,常常不变的量就叫常量._(¦3」∠) 变量 在 Java 中,任何一个变量都得有 ...
- kinect 深度图像去噪算法
算法设计思路 (1)读取16位深度图像到待处理图像帧组: (2)ROI区域计算 由于kinect 彩色摄像头和红外深度摄像头是存在视角偏差的,经过视角对齐后,得到的深度图像是有黑边的.此处通过取帧组第 ...
- Tomcat中使用commons-io-2.5发生的错误java.lang.ClassNotFoundException: org.apache.commons.io.IOUtils
关键词:IntelliJ IDEA.Tomcat.commons-io-2.5.jar.java.lang.ClassNotFoundException: org.apache.commons.io. ...
- python学习之老男孩python全栈第九期_day021知识点总结——包、异常处理
一. 包 # 把解决一类问题的模块放在同一个文件夹里 -- 包 # 创建目录代码# import os# os.makedirs('glance/api')# os.makedirs('glance/ ...
- cookie、session、分页
一.cookie HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情 ...
- git杂记-记录每次更新到仓库
git status 和 git diff的运用 git status 记录的是关于仓库文件是否有变更,例如是否被修改,是否被添加到暂村区.至于文件更改了什么内容该命令并不关心: git status ...
- 一类划分关系和指数级生成函数,多项式exp的关系
划分关系 姑且这么叫着 设满足性质 \(A\) 的集合为 \(S_A\),每个元素有标号 如果 \(S_B\) 是由若干个 \(S_A\) 组成的一个大集合 设 \(a_i\) 表示大小为 \(i\) ...