59.【C语言】内存函数(memmove函数)
2.memove函数
*简单使用
memove:memory move
cplusplus的介绍 点我跳转
对比第59篇的memcpy函数
对比memmcpy函数的介绍如下区别:
部分翻译
memmove多了:Copying takes place as if an intermediate buffer were used(复制就像中间的缓存区使用一样), allowing the destination and source to overlap.
memcpy多了:, and should not overlap (for overlapping memory blocks, memmove is a safer approach).
说明memmove允许source指针和destination指针有重叠
将arr[0]~arr[4]的内容复制到arr[2]~arr[6]中
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
int main()
{int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr1+2, arr1, 5* sizeof(int));return 0;
}
*模拟实现
设计一个函数sim_memmove,参数及类型与memmove相同
方案1
线索:上方cplusplus的翻译
可以在函数中设计一个缓存区数组buffer来转移数据
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
void* sim_memmove(void* dest, const void* src, size_t num)
{char buffer[1000] = { 0 };//最多移动1000个字符//s_src是save_source的缩写const char* s_src = (const char*)src;//s_dest是save_destination的缩写char* s_dest = (char*)dest;//保存返回值for (size_t i = 0; i < num; i++){buffer[i] = s_src[i];//s_src已经被强制类型转换过了,不用在循环的时候进行}src = s_src;for (size_t i = 0; i < num; i++){s_dest[i] = buffer[i];}return dest;
}int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };sim_memmove(arr+2, arr, 5* sizeof(int));return 0;
}
如果想让程序更安全
可以在开头加上:
由于函数的参数还有指针,按规范应该断言
// 如果 dest 和 src 重叠
if (dest == NULL || src == NULL || num == 0)
{return dest;
}// 确保不超过 1000 字节
if (num > 1000)
{return NULL; // 或者可以返回一个错误码
}
方案2
方案1可以优化,设计一个buffer数组会占用空间,只是需要考虑复制的方向
分为dest和src的部分是否有重叠进行讨论
1.有重叠
dest在src左侧
从src前向后复制,防止重叠
dest在src右侧
从src后向前复制,防止重叠
2.无重叠
从src前向后复制或从src后向前复制均可
比较dest和src的大小关系即可
代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
void* sim_memmove(void* dest, const void* src, size_t num)
{void* s_dest = dest;if (dest == NULL || src == NULL || num == 0) {return dest;}if (dest < src){while (num--){*(char*)dest = *(char*)src;dest = (char*)dest + 1;src = (char*)src + 1;}}else{while (num--){*((char*)dest + num) = *((char*)src + num);}}return s_dest;
}int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };sim_memmove(arr + 2, arr, 5 * sizeof(int));return 0;
}
总结
1.memcpy只考虑重叠的
2.memmove既考虑重叠又考虑不重叠的
建议复制字符串时用memmove