C语言的内存函数

1.memcpy的使用和模拟实现

复制代码
void * memcpy ( void * destination, const void * source, size_t num );
  • 这个函数的作用是将source的前num个字节拷贝到destination

  • 遇到'\0'并不会停止

  • 如果source与destination有任何重叠,拷贝结果是未定义的

看下面一段代码:

一个整形4个字节,拷贝爱arr2的前20个字节到arr1,即把arr1的前5个整形改为0;

但是如果我传的num并不是4的整数倍可能会出现特殊情况:

这里arr2的首元素是1234,其余全是0。1234的16进制为4D2(内存中的存储看图最右侧)

当运行memcpy后可以看到arr1的首元素的第一个字节被改为D2,转化成10进制正好是210。

或者说传参的两个地址并不是一个类型:

为什么会出现这种情况?:

结论1:memcpy是以字节为单位进行拷贝,尽量不要拿它来给char类型外的数据拷贝。

结论2:memcpy遇到'\0'不会停止

memcpy的模拟实现:

cpp 复制代码
#include<stdio.h>
#include<string.h>
char* my_memcpy(void* dest, const void* src, int num)
{
	char* str = (char*)dest;
	while (num--)
	{
		*((char*)dest) = *((char*)src);
		dest = (char*)dest+1;
		src = (char*)src + 1;
	}
	return str;
}
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	my_memcpy(arr2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr2[i]);
	}
	return 0;
}

2.memmove的使用和模拟实现

复制代码
void * memmove ( void * destination, const void * source, size_t num );

memmove基本同memcpy,但是它们两个的区别是 前者可以拷贝有重叠区域的两块数据;

先看为什么memcpy不能拷贝重叠的内存块:

而memmove很好的解决了这个问题:

具体是怎么个原理呢?

memmove的模拟实现:

cpp 复制代码
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_memmove(void* dest, const void* src, int num)
{
	assert(dest && src);
	char* str = (char*)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 str;
}
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 0 };
	my_memmove(arr1 + 2, arr1, 20);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
	return 0;
}

3.memset函数的使用

复制代码
void * memset ( void * ptr, int value, size_t num );

memset 顾名思义就是用来设置内存的,以字节为单位

4.memcmp函数的使用

复制代码
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
  • 比较从ptr1与ptr2往后的num个字节。

  • 比较的是字母序

返回值:

注:返回值在vs中是1 0 -1

相关推荐
不吃香菜学java5 小时前
Redis的java客户端
java·开发语言·spring boot·redis·缓存
xiaotao1315 小时前
02-机器学习基础: 监督学习——线性回归
学习·机器学习·线性回归
BestOrNothing_20155 小时前
C++零基础到工程实战(4.3.3):vector数组访问与遍历
c++·迭代器·stl·vector·动态数组
贵沫末5 小时前
python——打包自己的库并安装
开发语言·windows·python
charlie1145141915 小时前
通用GUI编程技术——图形渲染实战(三十三)——Direct2D与Win32/GDI互操作:渐进迁移实战
c++·图形渲染·gui·win32
文祐6 小时前
C++类之虚函数表及其内存布局(一个子类继承一个父类)
开发语言·c++
墨黎芜6 小时前
ArcGIS从入门到精通——地图符号、注记的初步使用
学习·arcgis·信息可视化
小李云雾6 小时前
FastAPI重要知识点---中间件(Middleware)
学习·程序人生·中间件·fastapi·middleware
zuowei28896 小时前
华为网络设备配置文件备份与恢复(上传、下载、导出,导入)
开发语言·华为·php
小夏子_riotous6 小时前
Docker学习路径——3、常用命令
linux·运维·服务器·学习·docker·容器·centos