我是靠谱客的博主 舒心冰棍,最近开发中收集的这篇文章主要介绍memcpy、memmove的模拟实现一.memcpy二.memmove一.memcpy二.memmove,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一.memcpy

声明

void *memcpy(void *str1, const void *str2, size_t n)

作用

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

模拟实现

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发生重叠时,无法需拷贝的数据可能被覆盖掉,导致无法达到所需的效果

举一个例子来解释

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

声明

void *memcpy(void *str1, const void *str2, size_t n)

作用

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

模拟实现

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发生重叠时,无法需拷贝的数据可能被覆盖掉,导致无法达到所需的效果

举一个例子来解释

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时,后拷贝

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的模拟实现一.memcpy二.memmove一.memcpy二.memmove所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部