本文转自:http://my.oschina.net/renhc/blog/36345

面试中如问到memcpy的实现,那就要小心了,这里有陷阱。

先看下标准memcpy()的解释:

1
2
void *memcpy(void *dst, const void *src, size_t n);
//If copying takes place between objects that overlap, the behavior is undefined.

注意下面的注释,对于地址重叠的情况,该函数的行为是未定义的。

事实上所说的陷阱也在于此,自己动手实现memcpy()时就需要考虑地址重叠的情况。

另外,标准库也提供了地址重叠时的内存拷贝函数:memmove(),那么为什么还要考虑重写memcpy()函数呢?

因为memmove()函数的实现效率问题,该函数把源字符串拷贝到临时buf里,然后再从临时buf里写到目的地址,增加了一次不必要的开销。

下面给出memcpy()的实现,为了与标准库函数区分,我们实现其包裹函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void *Memcpy(void *dst, const void *src, size_t size);
 
int main(int argc, char *argv[])
{
    char buf[100] = "abcdefghijk";
    //memcpy(buf+2, buf, 5);
    Memcpy(buf+2, buf, 5);
    printf("%s\n", buf+2);
}
 
void *Memcpy(void *dst, const void *src, size_t size)
{
    char *psrc;
    char *pdst;
 
    if(NULL == dst || NULL == src)
    {
        return NULL;
    }
 
    if((src < dst) && (char *)src + size > (char *)dst) // 自后向前拷贝
    {
        psrc = (char *)src + size - 1;
        pdst = (char *)dst + size - 1;
        while(size--)
        {
            *pdst-- = *psrc--;
        }
    }
    else
    {
        psrc = (char *)src;
        pdst = (char *)dst;
        while(size--)
        {
            *pdst++ = *psrc++;
        }
    }
 
    return dst;
}

【转】【C/C++】实现memcpy函数的更多相关文章

  1. memcpy函数用法

    memcpy函数用法 .分类: VC++ VC++ mfc matlab 2011-12-01 19:17 14538人阅读 评论(0) 收藏 举报 null 原型:extern void *memc ...

  2. C语言之memcpy函数

    昨天自己动手实现memcpy这个函数,用一个例程试了一下,结果正确,满心欢心,可是有些地方想不明白,于是百度了一下,结果自己写的函数简直无法直视. 觉得还是写个总结,以示教训. 先贴上我自己的函数: ...

  3. memcpy函数

    实现1:<高质量c++,c编程指南> void *mymemcpy(void *dst,const void *src,size_t num) { assert((dst!=NULL)&a ...

  4. memcpy函数的使用方法

    c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中. 1.函数原型 void *memcpy(void * ...

  5. memset memcpy函数

    memset 函数 1.其头文件为: #include<memory> 或者#include<string> 2.原型    看清是对每个字节,不是其类型 void *mems ...

  6. sprintf、strcpy 及 memcpy 函数区别

    这些函数的区别在于 实现功能 以及 操作对象 不同.strcpy 函数操作的对象是 字符串 ,完成 从 源字符串 到 目的字符串 的 拷贝 功能. sprintf 函数操作的对象 不限于字符串 :虽然 ...

  7. C语言memcpy函数的用法

    介绍 memcpy是memory copy的缩写,意为内存复制,在写C语言程序的时候,我们常常会用到它.它的函原型如下: void *memcpy(void *dest, const void *sr ...

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

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

  9. 利用memcpy函数实现float到QByteArray的相互转化

    一.为什么要实现float到QByteArry之间的相互转化 在总线通讯过程中(例如串口通讯),总线上传输的是字节数组变量,即ByteArray型的变量,在Qt中即为QbyteArray型变量.总线发 ...

随机推荐

  1. Maven3下的java web项目

    咱们使用Maven3构建一个j2ee项目,项目的成果是一个war包,只需把它部署在服务器上,就可以使用浏览器访问. 具体详细信息 参考  http://www.mossle.com/docs/mave ...

  2. 配置RAC到单节点standby的data guard

    1RAC主库准备 2创建物理备库 3主库调整参数 4测试DG

  3. Java面试题大全(一)

    JAVA相关基础知识 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题,而只是选择其中的一部分, ...

  4. C# 截取字符串

    1.根据单个分隔字符用split截取 例如 string st="GT123_1"; string[] sArray=st.split("_"); 即可得到sA ...

  5. 20145337《Java程序设计》第八周学习总结

    20145337<Java程序设计>第八周学习总结 教材学习内容总结 15.1日志 15.1.1日志API简介 使用日志的起点是logger类,logger实例的创建有许多要处理的要素,必 ...

  6. python 语料处理(从文件夹中读取文件夹中文件,分词,去停用词,去单个字)

    # -*- coding:utf8 -*- import os import jieba def splitSentence(inputFile): fin = open(inputFile, 'r' ...

  7. Web前端开发基础 第一天(Html和CSS)

    学习web前端开发基础技术需要掌握:HTML.CSS.JavaScript语言.下面我们就来了解下这三门技术都是用来实现什么的: 1. HTML是网页内容的载体.内容就是网页制作者放在页面上想要让用户 ...

  8. 【iCore3 双核心板】例程二十:LAN_TCPC实验——以太网数据传输

    实验指导书及代码包下载: http://pan.baidu.com/s/1pJY5uXH iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...

  9. 使用 readfile() 下载文件

    下载图片 <?php $file = 'monkey.gif'; if (file_exists($file)) { header('Content-Description: File Tran ...

  10. 前端文摘:Web 开发模式演变历史和趋势

    今天的<前端文摘>给大家分享一篇玉伯的文章.文章详细介绍了 Web 开发的四种常用模式以及未来可能成为流行趋势的 Node 全栈开发模式,相信你看了以后一定会有收获. 您可能感兴趣的相关文 ...