内存函数的介绍

Posted JayceSun449

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内存函数的介绍相关的知识,希望对你有一定的参考价值。

memcpy

从名字中我们就可以猜出这个函数的功能应该是有关内存拷贝的,它的基本格式为

void* memcpy(void* dest, const void* src, size_t num);

其中dest为目标内存,src为原内存,num表示需要拷贝的字节数,假如我们现在有

arr1[20] = {1,2,3,4,5,6,7,8,9,10};
arr2[20] = {0};

这样两个数组,我们想把arr1中的前四个元素拷贝arr2中应该怎么做呢?我们可以这样使用这个库函数

memcpy(arr2, arr1, 10*sizeof(int));

模拟memcpy的实现

void* my_memcpy(void* dest, const void* src, size_t num)
{
	int i = 0;
	void* ret = dest;
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

memmove

在实际运用时,我们对于那些内存有重叠的内存拷贝通常使用memmove函数,那么什么是内存重叠呢?

注意当我们想把图中红色方框内的数字拷贝到蓝色方框内时,他们中3和4的内存就是重叠的,试想如果利用我们刚刚模拟的my_memcpy来对这个数字进行交换会发生什么是呢?我们会发现首先3会被1覆盖4被2覆盖,目前为止都没什么问题,但之后给5的位置赋值时我们会发现,刚刚的3已经被赋值为1,所以5和6本应被赋值为3和4,结果最后却被赋值为1和2。所以我们的my_memcpy其实是不适用有重叠的内存拷贝的,但值得一提的是,vs中的memcpy是可以实现这一个功能的,说明vs的功能确实很强大,但笔者还是建议大家在有重叠内存拷贝中使用memmove,因为在大多数编译器底下的memcpy是无法实现这一功能的,所以为了咱们代码的通用性,还是建议读者们注意区分

memmove的模拟实现

void* my_memmove(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	if (dest == src)
	{
		return ret;
	}
	while (num--)
	{
		if (src < dest)
		{
			*((char*)dest + num) = *((char*)src+num);
		}
		if (src > dest)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	return 0;
}

关于这些代码的实现我想仔细地讲讲他们的逻辑,我们继续用上面的图来打比方,

比方说我想把红色框内的数字拷贝到蓝色框内,那我们按顺序拷贝显然不能成功,那我们应该如何实现功能呢?让我们看看按照倒序来拷贝会不会成功,我们先把4拷贝到6上3到5上,2到4上,1到3上,这样确实就成功了,那么再让我们想想,如果想把蓝色方框内的数字拷贝到红色方框内又该怎么做呢?倒序显然不能解决这个问题了,也就是说在源的内存大于目的内存时应该用顺序排序。那么我们就可以理解这些模拟代码了

memcmp

这是一个大小比较函数,基本格式为

int memcmp(void* arr1, void* arr2, size_t num);

arr1和arr2是用来比较大小的两个元素,num是需要比较的字节数,比方说我们有两个数组进行比较

	int arr1 = "123";
	int arr2 = "124";
	int ret = memcmp(arr1, arr2, 9);
	printf("%d\\n", ret);

arr1和arr2在内存中的存放方式为

我们可以看到在这两个数组的前八个字节中的元素都是相等的,而第9个字节中arr2的值更大,所以该函数会得出arr2更大的结论,所以它会返回一个负数,也就是说,当函数前面的元素更大时返回值为正,前面的值小时返回值为负,相同时返回0

memset

该函数的功能为,为某片内存空间赋值,基本格式

void* memset(void* dest, int c, size_t count);

dest为目标内存空间,c为改变的目标值,count为被改变的字节数
用例

int arr[] = {1,2,3,4,5};

此时arr后的内存为

然后我们添加代码

	memset(arr, 1, 20);	


此时arr后的内存就被重置了

以上是关于内存函数的介绍的主要内容,如果未能解决你的问题,请参考以下文章

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

Linux音频编程声卡介绍

窗函数介绍

VSCode自定义代码片段——声明函数

VSCode自定义代码片段8——声明函数

java内存流:java.io.ByteArrayInputStreamjava.io.ByteArrayOutputStreamjava.io.CharArrayReaderjava.io(代码片段