技术标签: C c语言 memcpy memmove 字节拷贝有无重叠
1. 题目一:不使用库函数,模拟实现内存拷贝函数memcpy的功能。
分析:
memcpy与strcpy不同,它是以字节为单位进行拷贝,每次拷贝一个字节,使用时,需要了解要拷贝的字节数。同时,因为它是以字节进行拷贝,所以无类型限制,即对任意类型均可以使用,而strcpy专用于字符串。
它的拷贝原理与strcpy类似,strcpy以“\0”为结束判断依据,而memcpy以要拷贝的字节数为结束判断依据。
代码如下:
例一:将src拷贝到dest中,主函数代码:
运行结果:
例二:当希望将src中的后续字符依次前移时,希望得到“xjgqg”时,主函数变为如下:
运行结果:
显然,与我们预期一致。
例三:当希望将src中的字符依次后移时,希望得到“bbxjgq”时,主函数变为如下:
此时,运行结果为:
这显然与我们预期的结果不同。此时,memcpy的功能已经不再适用,这里就需要用到memmove。
2. 题目二:模拟实现内存拷贝函数memmove的功能
同样是内存拷贝函数,两者之间的区别是什么呢?
这里,我们分析下两个字符串拷贝的几种情况:src表示源字符串,dest表示目标字符串。(因为dest是目标字符串,所以dest的长度一定大于src的长度)
1)src的地址小于dest的地址,二者不重叠。
2)src的地址大于dest的地址,二者不重叠。
3)src的地址小于dest的地址,二者不重叠。
4)src的地址小于dest的地址,二者有重叠(包括src完全包含在dest中的情况)。
如下图:
在处理前无重叠情况时,memcpy是适用的。再由上述例二,例三知,情形三memcpy也是适用的,而memcpy不适用于情形四。
而memmove就是用于解决情形四的,更确切的说,它对这四种情形都适用。前三种情形可以用与memcoy相同的方法接解决,
那么,情形四如何解决呢?
分析:
首先,我们需要知道上述例三的结果是如何产生的,在就上图而言,当src向dest拷贝时,a先拷给d,b拷给e,c拷给f,当要将d拷给g时,发现原来的有效d已经被a替代,使之失效 ,所以结果会变为abcabca,与例三的的结果类似。
其次,知道了出错原因,如何解决呢,上述叙述中,是从左往右拷贝的,这里,我们需要从右往左拷贝,即先拷贝g,依次往左进行,即使后面的拷贝会覆盖g但g已经发挥起作用,已经失效,所以,可以从右往左拷。
然后,src,dest初始是在字符串开头,那么需要移到右边什么地方呢?这时,就要考虑需拷贝的字节数了,若需拷贝k个字节,则src,dest分别从src+k,dest+k开始,依次往左拷。
最后,我们考虑下情形四的条件,从图中,可以观察到,src<dest且src+strlen(src)>dest。而其余情形方法与memcpy相同。
通过分析,代码编写如下:
对上述例三进行验证:
运行结果:
可以看到,结果与预期一致。
注意:
在对字符串进行拷贝时,首选strcpy;
在对内存进行拷贝时,可以选取memmove和memcpy,
而memmove的功能是兼容memcpy的,在检测字符串是否重叠时,就可以选择memcpy。
一、出现注入点的原因:程序员在编写代码时没有对用户输入的字符进行特殊处理。导致用户输入的特殊字符附带在参数中直接与数据库进行交互。二、注入过程1、打开一个连接地址:在网址后面加and 1=1 正常,and 1=2 错误。说明存在注入漏洞、2、判断一下数据库中的表and (select count(*) from admin)3、判断一下该网站有几个管理员。and
在Android studio中 android-support-v4报错,其实是在Android studio中用的是的知识androidx.viewpager.widget.ViewPager代替了android-support-v4.ViewPager。。。等引用不用导入android-support-vXXX的包支持(!!!可能!!!是已经过时了)...
opencv打包成exe在win7运行报错1、安装过程错误警告opencv版本:3.4.3打包环境:win10运行环境:win7opencv报错:2、解决方案opencv插件打包提取码: fp7v将 api-ms-win-downlevel-shlwapi-l1-1-0.dll【System32】 放到 c:\windows\System32将api-ms-win-downlevel-shlwapi-l1-1-0.dll【SysWOW64】 放到C:\Windows\SysWOW64
leetcode每日一题之回文链表题目链接:https://leetcode-cn.com/problems/palindrome-linked-list-lcci/submissions/题目描述:编写一个函数,检查输入的链表是否是回文的。示例 1:输入: 1->2输出: false 示例 2:输入: 1->2->2->1输出: true 解法1:自己的解法首先声明,本人的解法是通过了的。思想:首先遍历链表记录链表中的元素个数然后开辟一个数组,空间
Stacking Boxes BackgroundSome concepts in Mathematics and Computer Science are simple in one or two dimensions but become more complex when extended to arbitrary dimensions. Consider s
PGD攻击原论文地址——https://arxiv.org/pdf/1706.06083.pdf1.PGD攻击的原理 PGD(Project Gradient Descent)攻击是一种迭代攻击,可以看作是FGSM的翻版——K-FGSM (K表示迭代的次数),大概的思路就是,FGSM是仅仅做一次迭代,走一大步,而PGD是做多次迭代,每次走一小步,每次迭代都会将扰动clip到规定范围内。...
在java语言中String可以定义字符串变量,也可以定义字符串数组:length():用于求字符串变量的长度,即这个字符串有多少个字符;length:用于求字符串数组的长度,即这个数组有多少个字符串。1.字符串数组//Define an array of String.String[] strArray = { "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"}; System.out
0 入门篇1 史上最简单入门:java8的lambda中的map相关操作:基础及注意事项图文详解2 java8的lambda中collect接口案例及原理详解,官方文档解读1 以下是正文本文为转载,原文链接:https://blog.csdn.net/w605283073/article/details/829871571. 介绍本入门教程将介绍Ja...
目录Object(obj)object对象调用的方法object.hasOwnProperty(prop)object.isPrototypeOf(obj)object.propertyIsEnumerable(prop)Object上定义的静态方法Object.create(obj,propertiesObject)参数示例Object.getPrototypeOf(obj)Object.freeze(obj)Object.defineProperty(ob
找到sql server运行启动界面登陆界面使用 sql server身份验证老师的登陆密码 root123456成功登陆后
解决树莓派4B 3.5MM耳机接口没有声音的方法运行树莓派配置工具:sudo raspi-config一、选择1 System Options Configure system settin二、选择S2 Audio Select audio out through HDMI or 3.5mm jack三、在中Choose the audio output对话框中选择1 Headphones最后,选择Ok即可...
栏目导航Java开源OPEN文档OPEN搜索OPEN家园OPEN资讯OPEN论坛AAccordionAutoCompleteAnimationCCalendarChartsCornersCropperCanvasCarouselColorDDragDropDatePickerDhtmlGoodiesDocumentationEEditorEffectsExtJsFFormsFrameworkGGa