本文转自: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. app 尺寸

    web app 手机桌面logo尺寸大小(三种 ):114 72 57 

  2. Aspose Cells 添加数据验证(动态下拉列表验证)

    参考 :http://www.componentcn.com/kongjianjishu/kongjianjishu/2015-06-04/2781.html Aspose Cells是一款操作和处理 ...

  3. javascript对象的一点理解

    <script type="text/javascript"> /* js对象:对象的职责是调用属性和调用方法 */ //1.对象的创建的三种方式 var obj = ...

  4. BizTalk开发系列(十五) Schema设计之Qualified 与Unqualified

    XML Schema中的命名空间前缀限定包括对元素(Element)或属性(Attribute)的限定,即常见的如 “<ns0:root>...</ns0:root>”之类的格 ...

  5. js去除中间空格

    / 功能: 1)去除字符串前后所有空格 // 2)去除字符串中所有空格(包括中间空格,需要设置第2个参数为:g) function Trim(str,is_global) { var result;  ...

  6. 【转】Spring 获取web根目录 (Spring线程获取web目录/路径/根目录,普通类获取web目录)

    不使用Spring,怎样能在Listener启动的Thread中获取web目录,还真不完全确定.其实我觉得实际代码也很简单.就是基于普通的listener,然后在listener中获取web目录并放到 ...

  7. 【iCore3 双核心板】例程三十四:U_DISK_IAP_ARM实验——更新升级STM32

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

  8. 查留言总人数的sql语句

    select count(distinct user_id) from bidproduct

  9. 欢快的使用Unity JSON吧

    0x01:前言 Unity 5.3加入了UnityUtility类,意味着Unity终于有了自己原生态的JSON库.Unity主要用来游戏开发,JSON做为游戏开发中最受欢迎的配置文件.在官方没有库支 ...

  10. Oracle的日期时间范围查询

    Oracle日期时间范围查询 Sql代码 /* 日期时间范围查询 */ ---------- 创建日期时间测试表-------------------------------------------- ...