您的位置:首页 > 文旅 > 美景 > 库函数的模拟实现(memcpy)

库函数的模拟实现(memcpy)

2024/10/6 10:29:36 来源:https://blog.csdn.net/Yyyyyyyyyyyyds/article/details/141072774  浏览:    关键词:库函数的模拟实现(memcpy)

一、memcpy函数说明

还是老惯例,cplusplus的网址在这里啦,家人们保存好哟!

函数总结:

  1. 功能

    • 将 num 字节的数据从 source 指向的位置直接复制到 destination 指向的内存块。
  2. 直接复制

    • 数据复制是直接进行的,没有使用中间缓冲区。
  3. 数据类型无关性

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

    • 数据以二进制形式复制,不检查 source 中是否有终止空字符(null terminator)。
  5. 不检查溢出

    • 函数不检查目标数组是否有足够的空间,因此调用者需要确保目标数组足够大。
  6. 内存重叠问题

    • 如果 destination 和 source 指向的内存区域有重叠,使用 memcpy 可能会导致数据损坏。在这种情况下,应使用 memmove,库函数的模拟实现(memmove)
  7. 参数类型

    • destination 是指向目标数组的指针,类型转换为 void*
    • source 是指向要复制的数据源的指针,类型转换为 const void*
    • num 是要复制的字节数,类型为 size_t(无符号整型)。
  8. 返回值

    • 函数返回 destination 指针。
  9. 内存大小要求

    • 为了避免溢出,destination 和 source 指向的数组的大小至少应该是 num 字节,且这两个数组不应该重叠。
  10. 错误处理

    • 函数本身不进行错误检查,因此调用者需要确保传入的参数有效,且内存区域足够大以容纳复制的数据。

使用 memcpy 时,开发者需要确保提供的内存区域大小合适,并且正确处理任何可能的内存重叠问题,以避免数据损坏或程序崩溃。如果内存区域可能重叠,应优先使用 memmove 函数。

二、memcpy函数使用

为了让大家更加了解这个函数我们现在来使用一下

#include <stdio.h>
#include <string.h> // 包含memcpy函数的头文件int main() {// 定义两个整型数组int sourceArray[] = {10, 20, 30, 40, 50};int destinationArray[5] = {0}; // 初始化为0// 使用memcpy从sourceArray复制5个int大小的数据到destinationArraymemcpy(destinationArray, sourceArray, sizeof(sourceArray));// 打印destinationArray的内容以验证复制是否成功printf("Copied array elements:\n");for (int i = 0; i < 5; i++) {printf("%d ", destinationArray[i]);}printf("\n");return 0;
}

这段代码首先包含了 string.h 头文件,这是使用 memcpy 函数所必需的。然后定义了两个整型数组 sourceArraydestinationArraysourceArray 包含了要复制的数据,而 destinationArray 是目标数组,用于存储复制的数据。

我们使用 memcpy 函数将 sourceArray 的内容复制到 destinationArray。复制的字节数是通过 sizeof(sourceArray) 计算得来的,这确保了整个数组被复制。

复制完成后,使用一个循环和 printf 函数打印 destinationArray 的内容,以验证复制操作是否成功。

 

三、memcpy模拟实现

到了本期文章的重头戏啦,我们来根据前面对函数的总结进行模拟实现吧。

#include <stdio.h>
#include <assert.h>
#include <string.h>void* my_memcpy(void* dest, const void* src, size_t n) {assert(dest && src && n > 0); // 确保所有参数有效void* ret = dest;unsigned char* d = (unsigned char*)dest;const unsigned char* s = (const unsigned char*)src;for (size_t count = n; count > 0; --count) {*d++ = *s++;}return ret;
}int main() {int a[] = {1, 2, 3};int b[10] = {0};// 使用 my_memcpy 函数复制 a 数组到 b 数组size_t n = sizeof(a) / sizeof(a[0]); // 计算 a 数组的元素个数my_memcpy(b, a, n);// 打印 b 数组的内容size_t sz = sizeof(b) / sizeof(b[0]);for (size_t i = 0; i < sz; i++) {printf("%d ", b[i]);}printf("\n");return 0;
}

代码详解:

  1. 自定义 my_memcpy 函数

    • 函数原型:void* my_memcpy(void* dest, const void* src, size_t n),接受三个参数,分别代表目标内存地址、源内存地址和要复制的元素个数。
    • assert(dest && src && n > 0):确保 dest 和 src 非空且 n 大于 0,这是为了确保内存复制的安全性。
  2. 函数返回值

    • void* ret = dest:保存目标地址,以便最后返回。
  3. 内存复制逻辑

    • 将 dest 和 src 转换为 unsigned char* 类型的指针,以便按字节操作。
    • 使用一个循环,从 n 开始递减至 0,每次循环中将 src 指向的字节复制到 dest 指向的位置,然后递增两个指针。
  4. 返回目标地址

    • 函数返回目标地址 ret。
  5. 使用 my_memcpy

    • 计算 a 数组的元素个数 n,并将其作为参数传递给 my_memcpy 函数,同时传递 a 和 b 的地址。这将复制 a 的内容到 b

本期内容到此结束啦,大家自己动手试试吧。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com