我是靠谱客的博主 舒心冰棍,这篇文章主要介绍memcpy、memmove的模拟实现一.memcpy二.memmove一.memcpy二.memmove,现在分享给大家,希望可以做个参考。

一.memcpy

声明

复制代码
1
void *memcpy(void *str1, const void *str2, size_t n)

作用

将自str2往后的n个字节的数据,复制到str1往后的n个字节的内存当中

模拟实现

复制代码
1
2
3
4
5
6
7
8
9
void* my_memcpy(void* str1, const void* str2, int n) { while (n--) { *(char*)str1 = *(char*)str2; str1 = (char*)str1 + 1; str2 = (char*)str2 + 1; } }

注意

在使用过程中,str1与str2中的n个字节不能重叠。这也是memcpy很大的一个缺陷,而memmove可以很好的解决整个问题

二.memmove

在使用memcpy时,当str1与str2发生重叠时,无法需拷贝的数据可能被覆盖掉,导致无法达到所需的效果

举一个例子来解释

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void* my_memmove(void* str1, const void* str2, size_t n) { void* ret = str1; while (n--) { *(char*)str1 = *(char*)str2; str1 = (char*)str1 + 1; str2 = (char*)str2 + 1; } return ret; } int main() { int arr[] = {1,2,3,4,5,6,7,8,9,10}; my_memmove(arr+2, arr, 20); int i = 0; for (i = 0; i < 10; i++) printf("%d ", arr[i]); return 0; }

想要达到的效果是,将arr1为起始的20个字节的数据,存放到arr1+2后的20个字节的内存中。

原数组12345678910
目的数组12123458910
实际数组12121218910

这为什么呢?

一.memcpy

声明

复制代码
1
void *memcpy(void *str1, const void *str2, size_t n)

作用

将自str2往后的n个字节的数据,复制到str1往后的n个字节的内存当中

模拟实现

复制代码
1
2
3
4
5
6
7
8
9
void* my_memcpy(void* str1, const void* str2, int n) { while (n--) { *(char*)str1 = *(char*)str2; str1 = (char*)str1 + 1; str2 = (char*)str2 + 1; } }

注意

在使用过程中,str1与str2中的n个字节不能重叠。这也是memcpy很大的一个缺陷,而memmove可以很好的解决整个问题

二.memmove

在使用memcpy时,当str1与str2发生重叠时,无法需拷贝的数据可能被覆盖掉,导致无法达到所需的效果

举一个例子来解释

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void* my_memmove(void* str1, const void* str2, size_t n) { void* ret = str1; while (n--) { *(char*)str1 = *(char*)str2; str1 = (char*)str1 + 1; str2 = (char*)str2 + 1; } return ret; } int main() { int arr[] = {1,2,3,4,5,6,7,8,9,10}; my_memmove(arr+2, arr, 20); int i = 0; for (i = 0; i < 10; i++) printf("%d ", arr[i]); return 0; }

想要达到的效果是,将arr1为起始的20个字节的数据,存放到arr1+2后的20个字节的内存中。

原数组12345678910
目的数组12123458910
实际数组12121218910

这为什么呢?

正在上传…重新上传取消

重叠部分的数据,在拷贝过程中已经被覆盖了,数据已经丢失了

从这里不难发现,memcpy无法处理出现重叠的情况

在这时,我们可以使用memmove

memmove的参数,返回值等等与memcpy均相同,不过他可以处理重叠的情况

正在上传…重新上传取消

正在上传…重新上传取消 对比上下两个例子,不难发现重叠部分是分情况的,

一是与原数据前部分与目标地址重合,另一种是后部分与目标地址重合

想要处理重叠部分,重点便是先使用重叠部分的数据,防止重叠部分的数据被覆盖后,导致的数据丢失

可以通过str1 与 str2 的的地址位置关系来判断

目前的讨论是以重叠为前提的,不重叠时以下要讨论的两种方法都能实现

为了方便讨论,将memcpy中的拷贝方法称作为前拷贝,反之先拷贝高地址处数据的称之为后拷贝

先讨论一个特殊情况 

str1 == str2

 无论是前拷贝还是后拷贝,均无影响。

都是将数据本身赋值给本身

str1 > str2

重叠部分的数据位于源数据的后部分,应优先使用重叠部分

即应使用后拷贝

str1 < str2

重叠部分的数据位于源数据的前部分,应优先使用重叠部分

即应使用后拷贝

总体而言

当str1 < str2时,前拷贝

当str >= str2时,后拷贝

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void* my_memmove(void* str1, const void* str2, size_t n) { void* ret = str1; if (str1 < str2) { while (n--) { *(char*)str1 = *(char*)str2; str1 = (char*)str1 + 1; str2 = (char*)str2 + 1; } } else while(n--) *((char*)str1+n) = *((char*)str2+n); return ret; }

最后

以上就是舒心冰棍最近收集整理的关于memcpy、memmove的模拟实现一.memcpy二.memmove一.memcpy二.memmove的全部内容,更多相关memcpy、memmove内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(71)

评论列表共有 0 条评论

立即
投稿
返回
顶部