memcpy实现及优化

本文探讨了面试中常见的 memcpy 函数实现,强调了在处理函数指针和内存交集时的注意事项。当目标区域在源区域左侧,应从低位向高位复制;反之,则从高位向低位倒序复制。此外,当拷贝大小超过目标区域长度时,应抛出错误。文章还提到了通过地址对齐优化拷贝速度的方法,以及一种改进的实现策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是一道面试常考题,要注意的是,函数指针为void类型,注意转换。另一点是两个指针可能有交集,针对这一点,当Dest在Src左边时,从低位向高位复制,反之,从高位向低位倒序复制。另外当size大于Dest长度时将报错。

最简:

void* Memcpy(void *Dest, void *Src, unsigned int size){
    if(Dest==nullptr||Src==nullptr)
        return nullptr;
    char* tempDest=(char*) Dest;
    char* tempSrc=(char*) Src;
    if(Dest<Src){
        while(size--){
            *(tempDest++)=*(tempSrc++);
        }
    }
    else{
        tempDest+=size-1;
        tempSrc+=size-1;
        while(size--){
            *(tempDest--)=*(tempSrc--);
        }
    }
    return Dest;
}

改进:地址对齐时以CPU字长来拷贝,不对齐时按字节拷贝

void* Memcpy(void *Dest, void *Src, unsigned int size){
    if(Dest==nullptr||Src==nullptr)
        return nullptr;
    int* tempDest=(int*) Dest;
    int* tempSrc=(int*) Src;
    unsigned int newsize=size/4;
    unsigned int slice=size%4;
    if(Dest<Src){
        while(newsize--)
       
### memcpy实现方式及源码分析 `memcpy` 是 C/C++ 标准库中的一个函数,用于在内存中复制数据。它从源地址开始复制指定字节数的数据到目标地址。以下是关于 `memcpy` 的实现方式和源码的详细说明。 #### 1. 基本功能 `memcpy` 函数的功能是从源地址(`src`)复制指定数量的字节(`n`)到目标地址(`dest`)。需要注意的是,`memcpy` 不检查重叠区域,因此如果源和目标有重叠部分,可能会导致不可预期的结果。对于这种情况,应使用 `memmove`[^4]。 #### 2. 源码实现 以下是 `memcpy` 的一种常见实现方式: ```c void* memcpy(void* dest, const void* src, size_t count) { if (dest == NULL || src == NULL || count == 0) return dest; char* d = (char*)dest; const char* s = (char*)src; while (count--) { *d++ = *s++; } return dest; } ``` - **参数说明**: - `dest`:目标内存地址。 - `src`:源内存地址。 - `count`:需要复制的字节数。 - **实现逻辑**: - 首先检查输入参数是否有效,若无效则直接返回目标地址。 - 将 `dest` 和 `src` 转换为 `char*` 类型,以便逐字节操作。 - 使用 `while` 循环逐字节复制数据,每次复制后递增指针位置。 - 返回目标地址 `dest`。 #### 3. 性能优化 上述实现是一个简单的逐字节复制版本,但在实际应用中,为了提高性能,通常会采用更复杂的优化策略,例如按字(word)或双字(double word)进行复制。以下是一个优化版本的实现: ```c void* memcpy(void* dest, const void* src, size_t count) { char* d = (char*)dest; const char* s = (char*)src; if (count >= sizeof(size_t)) { size_t n = count / sizeof(size_t); const size_t* ps = (const size_t*)s; size_t* pd = (size_t*)d; for (; n > 0; n--) { *pd++ = *ps++; } s = (const char*)ps; d = (char*)pd; } for (; count > 0; count--) { *d++ = *s++; } return dest; } ``` - **优化点**: - 当复制的字节数较大时,先按 `size_t` 的大小进行整块复制,减少循环次数。 - 对于剩余的字节,再逐字节复制。 #### 4. 查看系统提供的 `memcpy` 源码 在现代操作系统中,`memcpy` 通常是用汇编语言实现的,以充分利用 CPU 的特性(如 SIMD 指令集)。以下是一些方法查看系统提供的 `memcpy` 源码: - **GNU libc**: - 如果使用的是 GNU libc,可以通过下载其源码包来查看 `memcpy` 的实现。 - 下载地址:[https://ftp.gnu.org/gnu/libc/](https://ftp.gnu.org/gnu/libc/) - 在源码中搜索 `sysdeps/x86_64/multiarch/memcpy-*.S` 文件,可以找到针对不同架构的实现。 - **Windows 平台**: - 在 Windows 上,`memcpy` 的实现位于 Visual Studio 的 CRT(C Runtime Library)中。 - 可以通过安装 Visual Studio 并查看其头文件和源码目录来找到相关实现。 #### 5. 注意事项 - `memcpy` 不检查内存重叠问题,若源和目标有重叠部分,可能会导致数据覆盖错误。此时应使用 `memmove`[^4]。 - 在多线程环境中调用 `memcpy` 时,需确保目标和源内存区域不会被其他线程同时访问,否则可能导致竞争条件[^3]。 #### 示例代码 以下是一个简单的测试代码,展示如何使用 `memcpy`: ```c #include <stdio.h> #include <string.h> int main() { const size_t size = 20; int a[size] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; int b[size]; memcpy(b, a, 10 * sizeof(int)); // 注意这里是字节数 for (int i = 0; i < size; ++i) printf("%d ", b[i]); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值