C进阶_内存库函数_和这群虫豸在一起,怎能搞好政治呢?

news2024/12/26 0:51:01

其实之前我写过这篇……但是不够详细!今天重新写一下。

目录

memcpy

模拟实现memcpy

memmove

模拟实现memmove


memcpy

它的函数原型是:

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

查阅文档它的文档:

Copy block of memory

Copies the values of num bytes from the location pointed to by source directly to the memory block pointed to by destination.

The underlying type of the objects pointed to by both the source and destination pointers are irrelevant for this function; The result is a binary copy of the data.

The function does not check for any terminating null character in source - it always copies exactly num bytes.

To avoid overflows, the size of the arrays pointed to by both the destination and source parameters, shall be at least num bytes, and should not overlap (for overlapping memory blocks, memmove is a safer approach).

可以知道它的作用是从source的位置开始向后复制num个字节的数据到destination的内存位置。

它遇到'\0'的时候并不会停下来,不会对停止字符做检查。

如果source和destination有任何的重叠,复制的结果都是未定义的。

请看示例:

#include <stdio.h>
#include <string.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[5] = { 0 };
	int i = 0;
	memcpy(arr2, arr1, 20);
	for (i = 0;i < 5;i++)
	{
		printf("%d\n", arr2[i]);
	}
	return 0;
}

这是将arr1中的前五个元素给arr2。

为什么memcpy参数最后是20呢?

这是因为memcpy是内存拷贝,参数代表拷贝的字节数。

而int型是4个字节,要拷贝arr1中前五个元素给arr2,参数就为4*5=20。

运行结果如下:

模拟实现memcpy

#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	//前->后
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;
	}
	return ret;
}

但是……有虫豸(Bug)!

和这群虫豸在一起,怎能搞好政治呢?

 一旦dest和src有重叠的部分,虫豸就产生了!

注意看,绿色方框是src,紫色方框是dest。

在拷贝时,会一个一个地将src的字符拷贝给dest。

如果是从前往后拷贝:

1到了原来3的位置,2到了原来4的位置,在这时3和4都已经没有了,那么5就成了1,6就成了2,7就成了1。

所以当函数调用完,dest里不是12345而是12121。

还有一种情况是从后往前拷贝:

5到了原来7的位置,4到了原来6的位置,3到了原来5的位置,2到了原来4的位置,1到了原来3的位置。这就不会出错!

如果src在dest之前,那就要从后往前拷贝。

同理,如果src在dest之后,就要从前往后拷贝。

总结下,dest的位置在第一个区域就要从前往后拷贝,在第二个区域就要从后往前拷贝,在第三个区域的话,从前往后拷贝和从后往前拷贝皆可~

那么该怎么实现这些功能,进而杀死虫豸?当然要请昆虫学家金载圭了!

memmove

它的函数原型如下:

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

请看文档:

Move block of memory

Copies the values of num bytes from the location pointed by source to the memory block pointed by destination. Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap.

The underlying type of the objects pointed by both the source and destination pointers are irrelevant for this function; The result is a binary copy of the data.

The function does not check for any terminating null character in source - it always copies exactly num bytes.

To avoid overflows, the size of the arrays pointed by both the destination and source parameters, shall be at least num bytes.

和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。

如果源空间和目标空间出现重叠,就得使用memmove函数处理。

模拟实现memmove

void* my_memmove(void* dest, const void*src, size_t num)
{
	void* ret = dest;
	assert(dest && src);
	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 ret;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/175207.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

帮助有一定计算机基础的人 快速复习并重新拾起C语言基础(数据类型篇)

数据类型 帮助有一定计算机基础的人 快速复习并重新拾起C语言基础C语言数据类型分类基本数据类型整型类型的分类整型类型的基本用法有符号与无符号的区别字符型数据转义字符char 类型的范围浮点数类型数据字符串常量字符串输入之scanf函数字符输入输出函数算术运算符比较运算符…

SPI-读写串行FLASH

简介 是由摩托罗拉公司提出的通讯协议&#xff0c;即串行外围设备接口&#xff0c;是一种高速全双工的通信总线。它被广 泛地使用在ADC、LCD等设备与MCU间&#xff0c;要求通讯速率较高的场合。特性 1、全双工&#xff08;即可以同时收发&#xff09;2、最少需要占用4条线&…

图解统计学 10 | 贝叶斯公式与全概率公式

文章目录概率联合概率条件概率全概率公式贝叶斯公式过年了&#xff0c;作为水果店老板的我们&#xff0c;一共进了三种水果&#xff0c;其中&#xff1a;西瓜&#xff1a;50个 香蕉&#xff1a;30个 橙子&#xff1a;20个 为了方便顾客挑选&#xff0c;放在如下的格子里&…

[Android]Shape Drawable

ShapeDrawable可以理解为通过颜色来构造的图形 <android.widget.Buttonandroid:id"id/button1"android:layout_width"wrap_content"android:layout_height"wrap_content"android:text"Button"android:background"drawable/sha…

MongoDB学习笔记【part4】SpringBoot集成MongoDB、MongoTemplate开发CURD

一、Spring Boot 集成 Mongodb spring-data-mongodb 提供了 MongoTemplate 与 MongoRepository 两种方式访问mongodb&#xff0c;MongoRepository 操作简单&#xff0c;但 MongoTemplate 更加灵活&#xff0c;我们在项目中可以灵活使用这两种方式操作mongodb。 第一步&#x…

铸造性能监控平台【grafana+influxdb/prometheus+Linux/Windows】

目录一、grafanainfluxdbjmeter1、前言2、安装grafana和influxdb3、启动grafana4、访问grafana5、启动influxdb6、配置influxdb和jmeter7、在grafana中显示数据8、其他模板二、grafanaprometheusexporter1、前言2、grafana启动3、exporter安装与运行4、prometheus安装与运行5、…

代码随想录算法训练营第23天 二叉树 java : 669. 修剪二叉搜索树108.将有序数组转换为二叉搜索树538.把二叉搜索树转换为累加树

文章目录LeetCode 669. 修剪二叉搜索树题目讲解思路LeetCode 108.将有序数组转换为二叉搜索树题目讲解思路LeetCode 538.把二叉搜索树转换为累加树题解思路总结LeetCode 669. 修剪二叉搜索树 题目讲解 思路 在1到3的区间选择 元素 如何超过3 或者 小于1 如果小于1 叫要考虑 …

NeRF: Representing Scenesas Neural Radiance Fieldsfor View Synthesis论文阅读

注意&#xff1a;和很多文章一样&#xff0c;在Google搜索到最终版本时&#xff0c;有链接指出其有7个历史版本&#xff0c;但内容较详细的却不是最终版本&#xff0c;而是ECCV (2020)版&#xff0c;阅读时可以两个版本配合着阅读。 1. 摘要 我们提出了一种方法&#xff0c;通…

202301读书笔记|《命运》蔡崇达

202301读书笔记|《命运》蔡崇达 《命运》是我读的蔡崇达的第二本书&#xff0c;第一本是《皮囊》印象最深的一句就是“肉体是拿来用来的&#xff0c;不是拿来伺候的。” 当时读完第一本就很受触动&#xff0c;这一次读完《命运》依然很触动我。作者真的很厉害&#xff0c;这个故…

SpringBoot看这一篇文章就够了

第一章 SpringBoot简介 第1节 SpringBoot是什么 1 21.SpringBoot是一个可以快速创建可运行的、独立的、生产级的基于Spring的应用程序 2.SpringBoot采用一种约定优于配置的设计理念,可以快速让用户创建出一个可运行的基于Spring的应用第2节 SpringBoot的优势 1 2 3 4 51.快速构…

nacos源码解析==SPI和spring.factories机制-服务注册-心跳发送-服务拉取-服务调用

Spring.Factories这种机制实际上是仿照java中的SPI扩展机制实现的 springboot核心基础之spring.factories机制 - 知乎 SpringBoot1IDEA编写一个自己的starter_一个java开发的博客-CSDN博客_idea创建spring starter spring-cloud-starter-alibaba-nacos-discovery 将要注册到…

know sth. new 大话C#的进阶必知点解析第1章 第5节 名贵中药材程序WPF显示图片报错,找不到资源? 什么原因

1 Ui布局代码&#xff1b; 布局方面&#xff0c;主要还是继承了原先的布局方式。包括图片的展示&#xff0c;也是用了最外层border边框的方式&#xff0c;边框加入背景颜色方式的图片展示&#xff1b; 去把目标图片进行显示出来&#xff0c;这个没有太多技术含量。 至于图片的…

Spring Boot操作数据库学习之整合Druid

文章目录一 Druid 简介二 配置数据源创建项目步骤及数据库内容三 整合操作3.1 添加Druid数据源依赖3.2 编写配置文件3.3 测试3.4 自定义绑定数据源设置3.5 导入Log4j的依赖&配置日志输出3.6 添加DruidDataSource组件3.7 测试3.8 配置 Druid 数据源监控3.9 配置过滤器一 Dru…

SAPIEN PowerShell Studio 介绍

PowerShell Studio是一款优秀的基于PowerShell研发的脚本编辑器&#xff0c;它拥有全新的代码分析、智能预选、xaml支持功能&#xff0c;能够给用户提供一套完整的软件开发环境&#xff0c;让用户能够更加轻松的工作&#xff0c;这样一来大家开发项目的效率就会大大提升。创建模…

Day866.binlogredoLog -MySQL实战

日志系统 Hi&#xff0c;我是阿昌&#xff0c;今天学习的是关于MySql的binlog&redoLog的内容。 一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块&#xff0c;最后到达存储引擎。 那么&#xff0c;一条更新语句的执行流程又是怎样的呢&#x…

人大金仓数据库的用户与角色

创建用户 create user 用户名 授予用户创建数据库权限 alter user 用户名 要给的权限 然后查看用户信息 \du 用户名 设置用户密码 没有口令不能登录 alter user 用户名 password ‘kingbase’; 修改用户的并发连接数 alter user 用户 connection limit 要设置的连接数; 修改…

as-if-serialhappens-before

一、as-if-serialas-if-serial语义的意思是&#xff1a;不管怎么重排序&#xff08;编译器和处理器为了提高并行度&#xff09;&#xff0c;&#xff08;单线程&#xff09;程序的执行结果不能被改变。编译器、runtime和处理器都必须遵守as-if-serial语义。 为了遵守as-if-seri…

java类成员/final/static都涉及到了2023025

类成员&#xff1a; 在Java类里只能包含成员变量、方法、构造器、初始化块、内部类&#xff08;包括接口、枚举&#xff09;这5种成员&#xff0c;目前已经介绍了前面4种&#xff0c;其中static可以修饰成员变量、方法、初始化块、内部类&#xff08;包括接口&#xff0c;枚举&…

显示器的相关知识

目录 显示器的作用 显示器的尺寸 人眼的可视角度 显示器的分辨率 显示器的刷新率 显示器的灰阶响应时间 显示器的色域 显示器的色深 显示器的色准 显示器的HDR参数 显示器的面板 画面撕裂 前言 导致画面撕裂的原因 防画面撕裂技术 视频的码率 显示器的作用 把…

Golang 多模块开发

Golang 多模块开发 今天学习下Golang中多模块的基础知识&#xff0c;学习多模块的运行原理&#xff0c;使用多模块的方式&#xff0c;可以让开发者的代码在其他多个模块中构建、运行。提高代码的复用&#xff0c;从而提高开发效率。 在今天的学习中&#xff0c;将在工作工作空…