内存函数memcpy,memmove详解

本文详细介绍了内存函数memcpy和memmove的区别,以及它们在处理不同类型数据和重叠区域时的使用场景。通过模拟实现,展示了如何避免覆盖问题。核心内容包括内存操作原理、函数原型和实际应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

内存函数

目录

前言

1.memcpy

1.1memcpy的模拟实现

2.memmove

 2.1memcpy模拟实现


前言

内存函数的作用是什么,为什么我们需要内存函数

首先大家都知道字符串操作函数例如:strstr,strlen,strcpy,字符串操作函数包含在头文件string.h中,而内存函数也包含在头文件string.h中,那为什么我们有了strncpy还需要memcpy呢,内存函数是以字节为单位改变内存里存储的值,直接访问地址,不会要求参数数据类型,比strncpy范围更广。

1.memcpy

memcpy的函数与strcpy作用相似但范围更广,strncpy是将一个字符串拷贝到另一个字符串,而memcpy是将一个数组拷贝到一个相同类型的数组里去。

void * memcpy ( void * destination, const void * source, size_t num );

第一个参数void* destination指的是目标数组即最终拷贝到的数组的首指针

第二个参数const void* source指的是被拷贝数组的首指针

第三个参数size_t num指的是将从source开始的num个字节拷贝给destination,一个字节一个字节拷贝

大家可以比较一下memcpy和strncpy

void * memcpy ( void * destination, const void * source, size_t num );

char * strncpy ( char * destination, const char * source, size_t num );

strncpy限制的数据类型为char,而memcpy为void不限制,所以memcpy可以处理更多类型的数据

int main()
{
	int dest[] = {1,2,3,4,5,6,7};
	int src[] = { 4,5,6,7 };
	int i;
	memcpy(dest, src, 16);//内存函数这里的size是以字节作为单位
	for (i = 0; i < (sizeof(dest)/4); i++)
	{
		printf("%d ", dest[i]);
	}
	return 0;
}

这段代码的输出是这样的

这里用的整型数组,我想让他传四个元素给dest,所以字节数为16(64位编译为32)

int main()
{
	char str[] = "abcdef";
	char str1[] = "hijk";
	memcpy(str, str1, 5);//如果要复制\0就是5,不复制就是4
	printf("%s", str);
}

这里用memcpy的结果和strcpy的结果是一样的

1.1memcpy的模拟实现

因为char型占一个字节,所以只要将传入的指针类型强转成char*,指针+1才会只跳过一个字节否则如果是指向int的指针,+1会直接跳过四个字节。

void my_memcpy(void* a, void* b,size_t n)
{
	int i;
	for (i = 0; i < n; i++)
	{
		*(char*)a = *(char*)b;//强转成char*一个字节一个字节拷贝
		a = (char*)a+1;
		b = (char*)b+1;
	}
}

2.memmove

void * memmove ( void * destination, const void * source, size_t num )

这三个参数和memcpy一模一样

第一个参数void* destination指的是目标数组即最终拷贝到的数组的首指针

第二个参数const void* source指的是被拷贝数组的首指针

第三个参数size_t num指的是将从source开始的num个字节拷贝给destination,一个字节一个字节拷贝

memmove是专门用来处理memcpy所处理不了的原空间和目标空间重叠的问题

如果我想要将1,2,3放在3,4,5的位置上,最终数组变成

 可是如果是memcpy的处理,当我们将1赋给3所在地址时那3就被覆盖,当你想将3赋给5所在的地址时就会发现3已经被1覆盖了,实际上你是将1赋给了5所在的位置。

 为什么会导致这样的结果,就是因为原空间和目标空间重叠的问题。

 memmove就是专门处理这样的问题

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	memmove(arr+2, arr, 12);
}

 

 2.1memcpy模拟实现

要模拟实现memcpy那么我们就要考虑覆盖的内容和目标数组和被拷贝数组的位置。

如果src<dest那么就要从后往前赋值,例如这里先将3存放到5所在的地址,再将2存放到4所在的地址,最后再将1赋给3

 如果src>dest那么就要从前往后赋值。

void my_memmove(void* dest, void* src, size_t num)//memmove模拟实现
{
	if (src > dest)
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
}

如有不对的地方还请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值