库函数的模仿实现(memmove)

打印 上一主题 下一主题

主题 984|帖子 984|积分 2952

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  一、memmove函数阐明

照旧老规矩给大家伙贴上cplusplus的网址。

函数总结:

  • 重叠安全

    • 纵然 destination 和 source 指向的内存地区有重叠,memmove 也能安全地复制数据,由于它利用了一个中间缓冲区。

  • 数据类型无关性

    • 函数在复制数据时不关心 source 和 destination 指针所指向对象的底层类型。

  • 二进制复制

    • 数据以二进制情势复制,不检查 source 中是否有停止空字符(null terminator)。

  • 正确字节数

    • 函数总是正确复制 num 指定的字节数。

  • 内存巨细要求

    • 为了避免溢出,destination 和 source 指向的数组的巨细至少应该是 num 字节。

利用 memmove 时,开发者须要确保提供的内存地区巨细合适,而且正确处理任何可能的内存重叠问题,以避免数据破坏或程序瓦解。

二、memmove函数利用


  1. #include <stdio.h>
  2. #include <string.h> // 包含memmove函数的头文件
  3. int main() {
  4.     char src[] = "Hello, World!";
  5.     char dest[20]; // 确保目标数组足够大以容纳源数组的内容
  6.     // 将src数组的内容复制到dest数组中
  7.     memmove(dest, src+6, strlen(src) + 1); // 包括空字符'\0'
  8.     printf("Source: %s\n", src);
  9.     printf("Destination after memmove: %s\n", dest);
  10.     return 0;
  11. }
复制代码

这段代码首先包罗了 string.h 头文件,这是利用 memmove 函数所必需的。然后界说了两个字符数组 src 和 dest。src 包罗了要复制的字符串,而 dest 是目标数组,用于存储复制的数据。我们利用 memmove 函数将 src 的内容复制到 dest,包括字符串的停止空字符 \0。复制完成后,利用 printf 函数打印出源字符串和目标字符串,以展示 memmove 函数的效果。
请注意,这个示例假设 dest 数组的巨细充足大,可以容纳 src 数组的全部内容。在现实利用中,你须要根据现实情况调整数组的巨细,并确保不会发生缓冲区溢出。

三、memmove模仿实现


  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include <string.h> // 包含size_t类型的定义
  4. void* my_memmove(void* dest, const void* src, size_t count) {
  5.     assert(dest && src);
  6.     void* ret = dest;
  7.     char* d = (char*)dest;
  8.     const char* s = (const char*)src;
  9.     if (s < d && s + count > d) {
  10.         // 逆序复制,因为src在dest之前且有重叠
  11.         s += count - 1;
  12.         d += count - 1;
  13.         while (count--) {
  14.             *d-- = *s--;
  15.         }
  16.     } else {
  17.         // 顺顺序复制,因为src在dest之后或者没有重叠
  18.         while (count--) {
  19.             *d++ = *s++;
  20.         }
  21.     }
  22.     return ret;
  23. }
  24. // 数组的打印
  25. void print(int* arr, size_t sz) {
  26.     for (size_t i = 0; i < sz; i++) {
  27.         printf("%d ", arr[i]);
  28.     }
  29. }
  30. int main() {
  31.     int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  32.     // 复制从arr[1]开始的5个元素到arr[3]的位置
  33.     my_memmove(arr + 3, arr + 1, 5);
  34.     size_t sz = sizeof(arr) / sizeof(arr[0]);
  35.     print(arr, sz); // 数组的打印
  36.     printf("\n");
  37.     return 0;
  38. }
复制代码
代码详解:


  • 自界说 my_memmove 函数

    • 函数原型:void* my_memmove(void* dest, const void* src, size_t count),担当三个参数,分别代表目标内存地点、源内存地点和要复制的字节数。
    • assert(dest && src):确保传入的目标和源地点不为空。
    • void* ret = dest:生存目标地点,以便末了返回。
    • 将目标和源地点转换为 char* 类型,以便按字节操纵。

  • 内存复制逻辑

    • 首先检查 src 和 dest 的相对位置。如果 src 在 dest 之前而且有重叠,利用逆序复制以避免数据覆盖。
    • 如果 src 在 dest 之后大概没有重叠,则利用顺次序复制。

  • 逆序复制

    • 当 src 在 dest 之前且有重叠时,将源指针 s 和目标指针 d 都移动到复制地区的末尾,然后逐字节复制,直到 count 减到 0。

  • 顺次序复制

    • 当 src 在 dest 之后大概没有重叠时,从 src 的开始位置逐字节复制到 dest 的开始位置,直到 count 减到 0。

  • 返回值

    • 函数返回目标地点 ret。

  • 打印函数

    • void print(int* arr, size_t sz):界说了一个打印数组的函数,担当一个整型指针和数组的巨细。

  • main 函数

    • 界说了一个整型数组 arr 并初始化。
    • 调用 my_memmove 函数,将 arr 中从索引 1 开始的 5 个元素复制到索引 3 的位置。注意这里 count 应该是元素个数而不是字节数,但由于 sizeof(int) 通常等于 4 字节,以是这里利用 5 作为 count 值是安全的,条件是数组元素巨细不超过 4 字节。
    • 计算数组巨细 sz 并利用 print 函数打印数组内容。

本期内容到此就竣事啦,自己动手实现一下吧。只有自己动手写出来了知识才是自己的哟!



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

何小豆儿在此

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表