Memcpy函数


一. 函数内容

** 1.1函数原型 **
void * Memcpy(void * dest,const void * src,size_t count)这是一个函数指针 接收的是一个地址 dest是接收地址的首地址,src是源首地址,count是接收目标的大小单位为字节 位于cstring或memcpy.h头文件中。

windows中Memcpy的函数原型  void* __cdecl memcpy(void* dst,const void* src,size_t count)
{void*ret=dst;
{extern void RtlMoveMemory(void *,const void *,size_t count);RtlMoveMemory(dst,src,count);
}
while(count--){*(char *)dst = *(char *)src;dst = (char *)dst+1;src = (char *)src+1;
}
return (ret);
}

使用注意事项:
1.-src地址是否为空,
2.-src和dest地址是否重合,是安全重合还是部分重合
3.当处与大块数据时候可能存在,效率低下问题。

改进之后的memcpy

   void *my_memcpy_byte(void *dst, const void *src, int n)
{if (dst == NULL || src == NULL || n <= 0)return NULL;char * pdst = (char *)dst;char * psrc = (char *)src;if (pdst > psrc && pdst < psrc + n){pdst = pdst + n - 1;psrc = psrc + n - 1;while (n--)*pdst-- = *psrc--;}else{while (n--)*pdst++ = *psrc++;}return dst;
}

linux版本

 void *memcpy(void *to, const void *from, size_t n)
{void *xto = to;size_t temp, temp1;if (!n)return xto;if ((long)to & 1) {char *cto = to;const char *cfrom = from;*cto++ = *cfrom++;to = cto;from = cfrom;n--;}if (n > 2 && (long)to & 2) {short *sto = to;const short *sfrom = from;*sto++ = *sfrom++;to = sto;from = sfrom;n -= 2;}temp = n >> 2;if (temp) {long *lto = to;const long *lfrom = from;
#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)for (; temp; temp--)*lto++ = *lfrom++;
#elseasm volatile ("    movel %2,%3\n""    andw  #7,%3\n""    lsrl  #3,%2\n""    negw  %3\n""    jmp   %%pc@(1f,%3:w:2)\n""4:    movel %0@+,%1@+\n""    movel %0@+,%1@+\n""    movel %0@+,%1@+\n""    movel %0@+,%1@+\n""    movel %0@+,%1@+\n""    movel %0@+,%1@+\n""    movel %0@+,%1@+\n""    movel %0@+,%1@+\n""1:    dbra  %2,4b\n""    clrw  %2\n""    subql #1,%2\n""    jpl   4b": "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1): "0" (lfrom), "1" (lto), "2" (temp));
#endifto = lto;from = lfrom;}if (n & 2) {short *sto = to;const short *sfrom = from;*sto++ = *sfrom++;to = sto;from = sfrom;}if (n & 1) {char *cto = to;const char *cfrom = from;*cto = *cfrom;}return xto;
}

二.函数使用

#include<stdio.h>
#include<string.h>
int main(void)
{char src[]="******************************";char dest[]="abcdefghijlkmnopqrstuvwxyz0123as6";printf("destination before memcpy:%s\n",dest);memcpy(dest,src,strlen(src));printf("destination after memcpy:%s\n",dest);return 0;
}
##输出为destination before memcpy:abcdefghijlkmnopqrstuvwxyz0123as6destination after memcpy: ******************************as6

Memcpy_s函数

   void *dest,size_t numberOfElements,const void *src,size_t count
);

以下是查看其他资料收集出来的

~~ 第一个参数为目标内存地址,第二个参数为目标内存缓冲大小,第三个参数为源内存地址,第四个为源内存缓冲的大小。返回值是一个错误码。
为什么这个返回值是错误码呢?因为这个版本中加入了基本的错误检测。如果源缓冲大小为0,即count为0,函数返回0,什么也不做。此函数没有对目标指针为NULL的情况,不做检查,所以你自己要注意检查。如果指针有值,但是是无效值,函数也没办法检查是否是有效内存,只是会搜集这些信息,在程序崩溃时提供调试需要的信息。
然后检查源地址是否为空或count是否大于sizeInBytes,两个条件有一个满足,函数中先将目标内存以sizeInBytes指定的大小调用memset函数清0.这里可以看出,如果sizeInBytes传入的大小超出目标缓冲区的大小,也是会带来隐患的,一旦清除了其他进程的或者其他线程的内存,都是带来问题,也很可能导致内存操作违规。所以,第二个参数的大小不能超过目标缓冲的大小,以字节为单位。然后程序搜集错误信息,最后返回错误码,并不会执行内存复制的过程。前面说的这是两个条件任意一个进入都会导致失败,所以在搜集信息时,程序会对进入的条件进行判断,然后进行搜集。
只有这些检查通过,才会调用memcpy函数执行内存复制过程。而第二个参数只是内部用来检测和清除目标内存而使用的。
函数memcpy_s执行完毕后返回0,所以检查返回值是否为0不能判断是否成功。但是返回值为非零那就是失败了。
虽然说加上_s版本的函数是安全版本,但是也是会出现问题的,使用时也要注意,即使有时候不崩溃,但是一旦改写了其他的线程的内存,必然导致程序运行不正常,因为线程的数据被破坏,至少逻辑会出错。
不过,_s版本函数提供了一定的检测,并且在release版本也可以报错,可以进一步调试问题,而memcpy则在release版本中不会报错 ~~

  --函数  memcpy_s( void *dest, size_t numberOfElements,   const void *src, size_t count ),先申请了一个缓冲区大小,为numberofelements,当count超过这个缓冲区的时候就开始溢出可能影响内存中下一个地址

C++的Memcpy与Memcpy_s函数解析相关推荐

  1. C语言 memcpy和memcpy_s区别 - C语言零基础入门教程

    目录 一.memcpy 和 memcpy_s 函数区别 1.语法对比 memcpy_s 函数语法 memcpy 函数语法 2.memcpy 和 memcpy_s 相同点 3.memcpy 和 memc ...

  2. main() 函数解析(一)——Linux-0.11 剖析笔记(六)

    文章目录 1. 宏定义`_syscall0` 2. `setup.s`读取的参数 3. 读取CMOS实时时钟信息 3.1 `outb_p(value,port)` 3.2 `inb_p(port)` ...

  3. main函数解析(一)——Linux-0.11 学习笔记(五)

    main()函数解析(一)--Linux-0.11 学习笔记(五) 经过了前面的各种铺垫,终于来到了main函数.这篇博客的任务是把init/main.c讲清楚.由于牵扯到很多的函数调用,要想一次就说 ...

  4. C语言 memcpy_s 函数 - C语言零基础入门教程

    目录 一.memcpy_s 函数简介 1.memcpy 函数报错:error C4996 2.memcpy 函数没有方法来保证有效的缓冲区尺寸,使用不安全 二.memcpy_s 函数语法 三.memc ...

  5. C语言 memcpy 和 strcpy 函数区别 - C语言零基础入门教程

    目录 一.memcpy 函数/strcpy 函数简介 二.memcpy 函数/strcpy 函数实战 1.strcpy 函数属于字符串拷贝 2.memcpy 函数属于内存拷贝 三.猜你喜欢 零基础 C ...

  6. C语言中memcpy()和memcpy_s()的区别

    1.memcpy()函数 原型:extern void *memcpy(void *dest, void *src, unsigned int count); 用法:#include "st ...

  7. C++【vector容器模拟实现函数解析】

    文章目录 vector容器&&模拟实现函数解析 一.vector介绍使用 二.vector 迭代器失效问题 三.vector容器模拟实现及函数解析 3.1vector构造函数指针初始化 ...

  8. linux网络编程函数解析之——setsockopt / getsockopt用法

    linux网络编程函数解析之--setsockopt / getsockopt用法 工程中无线传输方面的东西用到了setsockopt(),getsockopt().网上相关博客很多,而且类似,原文出 ...

  9. oracle rpad mysql_Oracle生成不重复票号与LPAD,RPAD与NEXTVAL函数解析

    SELECT TO_CHAR(SYSDATE,'YYMMDD')||LPAD(REFUNDSEQ.NEXTVAL,6,'0') AS RES_ORDER_NO FROM DUAL 该语句拼接 时间 与 ...

  10. json数据解析_VBA 实践指南 -- Split函数解析Json数据

    什么是JSON? JSON(JavaScript Object Notation) 是一种及其轻量级的数据交换格式,它是 ECMAScript (欧洲计算机协会制定的JavaScript规范)的一个子 ...

最新文章

  1. 命令行编译运行CSharp文件
  2. mysql查询每小时数据和上小时数据的差值
  3. Vector Enumeration
  4. linux 进程的vss rss uss,内核/内存管理中的VSS/RSS/PSS/USS
  5. C++Primer学习笔记:第2章 变量和基本类型
  6. 身份证号有效性检验代码 (python)
  7. 道路里程桩号标注_划重点!我区国、省道交通标志及里程桩“变脸”了,今后开车更享受~...
  8. 系统学习深度学习(十四)--权重初始化Xavier
  9. KVM(二)CPU 和内存虚拟化
  10. 计算机毕设(附源码)JAVA-SSM基于的网上拍卖系统
  11. 雨滴桌面显示html,如何用雨滴桌面设置美观的桌面天气插件
  12. Android Studio中Spinner控件的使用方法2-2
  13. 创业基础(第六章:创业资源及其管理) 来自高校:全国大学生创新创业实践联盟 分类:创新创业 学习规则:按序学习
  14. 深入了解现代 Web 浏览器(第 4 部分)【合成器线程详解】
  15. GIF制作软件哪个好,怎么制作搞笑GIF
  16. Nginx反向代理后无法获取header带下划线的头信息
  17. 神经网络入门书籍推荐,神经网络方向研究生
  18. java 控制台输入
  19. 使用Fiddler5和雷电模拟器4.0.83的抓包配置
  20. tomcat安装配置.md

热门文章

  1. extjs中的flex_Extjs 教程
  2. 关于消灭冲击波的蠕虫
  3. 咸宁php培训,PHP培训
  4. 关于转换QQ消息中系统表情,自定义表情和截图的函数
  5. su vary注册机_vray for sketchup2018下载
  6. 入门SVN基础使用教程
  7. C语言规范标准-C99(中文版) 完整版正式发布
  8. WebView 加载网页 加载资源 总结 MD
  9. 整理一下CCF推荐期刊会议(A类)
  10. Maven详细安装教程