马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
一、memmove函数阐明
照旧老规矩给大家伙贴上cplusplus的网址。
函数总结:
- 重叠安全:
- 纵然 destination 和 source 指向的内存地区有重叠,memmove 也能安全地复制数据,由于它利用了一个中间缓冲区。
- 数据类型无关性:
- 函数在复制数据时不关心 source 和 destination 指针所指向对象的底层类型。
- 二进制复制:
- 数据以二进制情势复制,不检查 source 中是否有停止空字符(null terminator)。
- 正确字节数:
- 内存巨细要求:
- 为了避免溢出,destination 和 source 指向的数组的巨细至少应该是 num 字节。
利用 memmove 时,开发者须要确保提供的内存地区巨细合适,而且正确处理任何可能的内存重叠问题,以避免数据破坏或程序瓦解。
二、memmove函数利用
- #include <stdio.h>
- #include <string.h> // 包含memmove函数的头文件
- int main() {
- char src[] = "Hello, World!";
- char dest[20]; // 确保目标数组足够大以容纳源数组的内容
- // 将src数组的内容复制到dest数组中
- memmove(dest, src+6, strlen(src) + 1); // 包括空字符'\0'
- printf("Source: %s\n", src);
- printf("Destination after memmove: %s\n", dest);
- return 0;
- }
复制代码
这段代码首先包罗了 string.h 头文件,这是利用 memmove 函数所必需的。然后界说了两个字符数组 src 和 dest。src 包罗了要复制的字符串,而 dest 是目标数组,用于存储复制的数据。我们利用 memmove 函数将 src 的内容复制到 dest,包括字符串的停止空字符 \0。复制完成后,利用 printf 函数打印出源字符串和目标字符串,以展示 memmove 函数的效果。
请注意,这个示例假设 dest 数组的巨细充足大,可以容纳 src 数组的全部内容。在现实利用中,你须要根据现实情况调整数组的巨细,并确保不会发生缓冲区溢出。
三、memmove模仿实现
- #include <stdio.h>
- #include <assert.h>
- #include <string.h> // 包含size_t类型的定义
- void* my_memmove(void* dest, const void* src, size_t count) {
- assert(dest && src);
- void* ret = dest;
- char* d = (char*)dest;
- const char* s = (const char*)src;
- if (s < d && s + count > d) {
- // 逆序复制,因为src在dest之前且有重叠
- s += count - 1;
- d += count - 1;
- while (count--) {
- *d-- = *s--;
- }
- } else {
- // 顺顺序复制,因为src在dest之后或者没有重叠
- while (count--) {
- *d++ = *s++;
- }
- }
- return ret;
- }
- // 数组的打印
- void print(int* arr, size_t sz) {
- for (size_t i = 0; i < sz; i++) {
- printf("%d ", arr[i]);
- }
- }
- int main() {
- int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
- // 复制从arr[1]开始的5个元素到arr[3]的位置
- my_memmove(arr + 3, arr + 1, 5);
- size_t sz = sizeof(arr) / sizeof(arr[0]);
- print(arr, sz); // 数组的打印
- printf("\n");
- return 0;
- }
复制代码 代码详解:
- 自界说 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。
- 返回值:
- 打印函数:
- 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企服之家,中国第一个企服评测及商务社交产业平台。 |