库函数memcpy()与memmove()实现

本文对比分析了memcpy与memmove两个函数的区别。当遇到内存重叠情况时,memcpy会报错,而memmove则能够正确处理。通过具体的代码实现展示了这两种函数的工作原理。
根据MSDN文档,当源区域与目标区域存在重叠时,memcpy()函数报错,而memmove()函数可以处理重叠情况!
 1/* 
 2 * 函数名: memcpy 
 3 * 功  能: 从源source中拷贝n个字节到目标destin中 
 4 * 用  法: void *memcpy(void* destin, const void* source, size_t n); 
 5 * 说  明: 内存拷贝
 6*/

 7
 8#include <stdio.h> 
 9#include <conio.h>   //getch头文件
10#include <assert.h>  //assert头文件
11
12typedef unsigned char byte
13//typedef unsigned int size_t;
14
15
16/*
17memcpy函数,如果内存重叠则报错
18*/

19//src要保留
20void* memcpy(void* dst,const void* src,size_t count) 
21{
22    byte* pbTo = (byte*)dst; 
23    byte* pbFrom = (byte*)src; 
24    assert(dst!= NULL && src != NULL);//不能存在空指针
25    assert(pbTo >= pbFrom+count || pbFrom >= pbTo + count);//防止内存重叠(overlap) 
26    while (count-- > 0
27    
28        *pbTo++ = *pbFrom++
29    }
 
30    return dst; 
31}

32
33/*
34memmove函数,考虑了内存重叠的情况
35*/

36//src可以不保留
37void* memmove(void* dst,const void* src,size_t count) 
38{     
39    byte* pbTo = (byte*)dst; 
40    byte* pbFrom = (byte*)src; 
41    assert(dst != NULL && src != NULL);//不能存在空指针
42    if (dst <= src || pbTo >= pbFrom + count)// 
43    
44        while (count-- > 0
45        
46            *pbTo++ = *pbFrom++; //按递增拷贝
47        }
 
48    }
 
49    else  //
50    
51        pbTo = pbTo + count -1;//overlap的情况,从高位地址向低位拷贝 
52        pbFrom = pbFrom + count -1
53        while (count-- > 0
54        
55            *pbTo-- = *pbFrom--; //按递减拷贝
56        }
 
57    }
 
58    return dst; 
59}

60
`memcpy` 是 C 语言标准库 `<string.h>` 中提供的一个函数,用于将指定数量的字节从一个内存区域复制到另一个内存区域。其函数原型为: ```c void *memcpy(void *dest, const void *src, size_t n); ``` 该函数接受三个参数:目标内存区域 `dest`、源内存区域 `src` 和要复制的字节数 `n`。函数返回指向目标内存区域的指针 `dest`。 ### 使用示例 以下是一个使用 `memcpy` 的简单示例,演示如何将一个整型数组的内容复制到另一个数组中: ```c #include <stdio.h> #include <string.h> int main() { int arr1[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int arr2[10] = {0}; memcpy(arr2, arr1, sizeof(arr1)); // 复制 arr1 的全部内容到 arr2 for (int i = 0; i < 10; i++) { printf("%d ", arr2[i]); } return 0; } ``` 在该示例中,`memcpy` 用于将 `arr1` 的内容复制到 `arr2` 中,`sizeof(arr1)` 用于指定要复制的总字节数[^3]。 ### 注意事项 `memcpy` 不适合用于源内存区域和目标内存区域重叠的情况。在这种情况下,可能会导致数据损坏,因为 `memcpy` 没有处理重叠区域的机制。为了安全地处理这种情况,应使用 `memmove` 函数,它能够正确处理源和目标内存区域重叠的情况[^1]。 ### 自定义实现 以下是一个简单的 `memcpy` 自定义实现示例,展示了如何通过逐字节复制来实现该功能: ```c #include <stdio.h> #include <assert.h> void* my_memcpy(void* dest, const void* src, size_t num) { void* ret = dest; assert(dest && src); // 确保参数有效 while (num--) { *(char*)dest = *(char*)src; // 逐字节复制 dest = (char*)dest + 1; src = (char*)src + 1; } return ret; } int main() { int arr1[] = {1, 2, 3, 4, 5, 6}; int arr2[10] = {0}; my_memcpy(arr2, arr1, 20); // 复制前 20 个字节 for (int i = 0; i < 6; i++) { printf("%d ", arr2[i]); } return 0; } ``` 此实现通过将 `dest` 和 `src` 强制转换为 `char*` 类型,实现了逐字节的复制操作。`assert` 被用来确保传入的指针非空,以避免无效指针访问的问题[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值