实现memcpy()函数过程总结

发布时间 2023-05-31 15:40:30作者: xiazichengxi

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的实现会变得复杂,反而影响拷贝效率。

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