首页 > 其他分享 >实现memcpy()函数过程总结

实现memcpy()函数过程总结

时间:2023-05-31 15:44:43浏览次数:50  
标签:总结 src 函数 -- dst memcpy ++ && void

1. 按字节实现

1)初步版本


void* my_memcpy(void* dst,const void *src,int n){
    if(dst == NULL && src == NULL && n <= 0) return NULL;
    char* s = (char*)src;
    char* d = (char*)dst;
    while(n--){
            *d++ = *s++;
    }
    return dst;
}

2)考虑写覆盖的版本


void* my_memcpy(void* dst,const void *src,int n){
    if(dst == NULL && src == NULL && n <= 0) return NULL;
    char* s = (char*)src;
    char* d = (char*)dst;
    //写覆盖
    if(d > s && d < s + n){
        //从后往前写
        d = d+n-1;
        s = s+n-1;
        while(n--){
            *d-- = *s--;
        }
    }
    else{
        while(n--){
            *d++ = *s++;
        }
    }
    return dst;
}

2. 四字节拷贝


void* my_memcpy(void* dst,const void *src,int n){
    if(dst == NULL && src == NULL && n <= 0) return NULL;
    
    int* s = (int*)src;
    int* d = (int*)dst;

    char* tmp1 = NULL;
    char* tmp2 = NULL;

    int c1 = n/4;
    int c2 = n%4;
    //写覆盖
    if(d > s && d < (char*)s + n){
        //从后往前写
        tmp1 = (char*)d+n-1;
        tmp2 = (char*)s+n-1;
        while(c2--){
            *tmp1-- = *tmp2--;
        }
        //考虑字节偏移
        tmp1++;
        tmp2++;
        d = (int*)tmp1;
        s = (int*)tmp2;
        d--;
        s--;
        while(c1--){
            *d-- = *s--;
        }
    }
    else{
        while(c1--){
            *d++ = *s++;
        }
        tmp1 = (char*)d;
        tmp2 = (char*)s;
        while(c2--){
            *tmp1++ = *tmp2++;
        }
    }
    return dst;
}

2. 更深层的优化

考虑内存对齐

浅谈CPU内存访问要求对齐的原因 – 仰望苍天思寰宇 (yangwang.hk)

[解析内存对齐 - 浅墨浓香 - 博客园 (cnblogs.com)](https://yangwang.hk/?p=773)

如果src,dst的地址是不对齐的,读写效率变低。

通过代码实现不对齐的拷贝,memcpy的实现会变得复杂,反而影响拷贝效率。

这种不对齐情况我们可以预先避免,因为编译器在给我们分配空间时是按照内存对齐进行分配的

标签:总结,src,函数,--,dst,memcpy,++,&&,void
From: https://www.cnblogs.com/lihaoxiang/p/17446320.html

相关文章

  • When Cyber Security Meets Machine Learning 机器学习 安全分析 对于安全领域的总结
    链接:http://ucys.ugr.es/jnic2016/docs/MachineLearning_LiorRokachJNIC2016.pdf https://people.eecs.berkeley.edu/~adj/publications/paper-files/SecML-MLJ2010.pdf一些关键点:算了,不总结了。......
  • 欧拉函数与容斥
    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意:给定五个数,其中有和,求满足条件的有序对的个数。题目中    明确说在所有的输入中。分析:问题可以转化为和时,的有序对的个数。那么先比较和的    大小,相同的部分可以用欧拉函数的累加计算,没有公共的部分用容斥计算......
  • 关于C++字符串的一些函数
    其实印象里,c的char用法反倒比c++的string深一点,可能是因为我对string的运用太少了吧。 提到C++的string,就得先提一下首先提一下C的char类型,毕竟C++是根据C延展过来的,继承了C的特性,而且C本身是没有string这个东西的。 char是什么?一个关键字,用于声明一个变量是字符类型。好吧,......
  • golang实现设计模式之工厂模式总结-代码、优缺点、适用场景
    工厂模式也是一种创建型模式,它与简单工厂不同的是将实例的创建推迟到具体的工厂类方法中实现,每一种产品生成一个对应的工厂,从而替换掉简单工厂方法模式中那个静态工厂方法。所以在工厂模式中,不同产品就由不同的工厂生产,每次增加产品时,我们就不需要在类似在简单工厂中,在统一的工厂......
  • Python 函数
    函数返回多个返回值defmultiple_return_value():importdatetimed=datetime.date.today()val_1='年份为:{}'.format(d.year)val_2='月份为:{}'.format(d.month)returnval_1,val_2#只需在return关键字后跟多个值(依次用逗号分隔)val=mult......
  • python 中 re.match和re.search()函数
     两者都返回首次匹配字符串的索引,re.match函数只从头开始匹配,re.search函数不限制只从头开始匹配。001、re.match函数[root@PC1test2]#python3Python3.10.9(main,Mar12023,18:23:06)[GCC11.2.0]onlinuxType"help","copyright","credits"or"license"......
  • C/C++杂记:虚函数的实现的基本原理
    1.概述简单地说,每一个含有虚函数(无论是其本身的,还是继承而来的)的类都至少有一个与之对应的虚函数表,其中存放着该类所有的虚函数对应的函数指针。例:其中:B的虚函数表中存放着B::foo和B::bar两个函数指针。D的虚函数表中存放的既有继承自B的虚函数B::foo,又有重写(override)了基......
  • C/C++杂记:深入理解数据成员指针、函数成员指针
    1.数据成员指针对于普通指针变量来说,其值是它所指向的地址,0表示空指针。而对于数据成员指针变量来说,其值是数据成员所在地址相对于对象起始地址的偏移值,空指针用-1表示。例:代码示例:structX{inta;intb;};#defineVALUE_OF_PTR(p)(*(long*)&p)int......
  • 开源软件架构总结之——Bash(readline做输入交互式,词法语法分析,进程交互)
    第3章TheBourne-AgainShellBash的主要组件:输入处理,解析,单词展开(wordexpansion)和其他命令处理,管道(pipeline)中的命令执行。这些组件构成一个流水线(pipeline),从键盘或脚本中获取字符,然后逐步转化为命令。图3.1Bash组件结构 3.7.经验教训3.7.1.什么是重要的参与到Bash项目......
  • 【C++】c++单继承、多继承、菱形继承内存布局(虚函数表结构)
    单继承:只有一个基类和一个派生类classBase{public:virtualvoidfun1(){cout<<"Base::func1()"<<endl;}virtualvoidfun2(){cout<<"Base::func2()"<<endl;}private:intb;......