linux内核中memcpy和memmove函数的区别和实现
来源:互联网 发布:gta5n卡优化驱动 编辑:程序博客网 时间:2024/06/07 07:02
linux内核中memcpy和memmove函数的区别和实现
Kernel version:2.6.32
CPU architecture:ARM
Author:ce123(http://blog.csdn.net/ce123)
嵌入式开发交流群:280352802,欢迎您的加入!
- memcpy是把src指向的对象中的size个字符拷贝到dest所指向的对象中,返回指向结果对象的指针.
- memmove也是把src指向的对象中的size个字符拷贝到dest所指向的对象中,返回指向结果对象的指针,但这两个函数在处理内存区域重叠的方式不同.
内存重叠问题是指目的地址的内存空间的首地址,包含在源内存空间中,这两段内存空间有了交集,因而在使用memcpy进行内存复制操作时,这段重叠的内存空间会被破坏.这种情况在应用程序级代码中一般不会出现的,而在驱动或内核级代码中要十分小心,尽量使用memmove函数.
memcpy对内存空间有要求的,dest和src所指向的内存空间不能重叠,否则复制的数据是错误的.下面具体讲解一下这个错误是如何产生的.
如果内存空间布局入下图所示:
src所指向的内存空间后面部分数据被新拷贝的数据给覆盖了(也就是dest<=src+size).所以拷贝到最后,原来的数据肯定不是原来的数据,拷贝的数据也不是想要的数据,使用memcpy函数可以得到错误的结果.
再者,如果内存空间布局入下图所示:
虽然原来的数据不再是原来的数据(dest+size>=src),但拷贝的数据是原来的数据,使用memcpy函数可以得到正确的结果.因此,在使用memcpy这个函数之前,还需要做一个判断,如果dest<=src你才能使用这个函数不过完全没有必要,你直接使用memmove函数就可以了.memmove在拷贝之前就做了一个判断,如果dest <= src,就按照memcpy的思路拷贝,如果dest>src怎么办呢,看函数,它是从后面往前拷贝,这样就能正确拷贝数据了.根据上面的分析,理解下面的代码应该是一件很容易的事情.
551 #ifndef __HAVE_ARCH_MEMCPY552 /**553 * memcpy - Copy one area of memory to another554 * @dest: Where to copy to555 * @src: Where to copy from556 * @count: The size of the area.557 *558 * You should not use this function to access IO space, use memcpy_toio()559 * or memcpy_fromio() instead.560 */561 void *memcpy(void *dest, const void *src, size_t count)562 {563 char *tmp = dest;564 const char *s = src;565 566 while (count--)567 *tmp++ = *s++;568 return dest;569 }570 EXPORT_SYMBOL(memcpy);571 #endif572 573 #ifndef __HAVE_ARCH_MEMMOVE574 /**575 * memmove - Copy one area of memory to another576 * @dest: Where to copy to577 * @src: Where to copy from578 * @count: The size of the area.579 *580 * Unlike memcpy(), memmove() copes with overlapping areas.581 */582 void *memmove(void *dest, const void *src, size_t count)583 {584 char *tmp;585 const char *s;586 587 if (dest <= src) {588 tmp = dest;589 s = src;590 while (count--)591 *tmp++ = *s++;592 } else {593 tmp = dest;594 tmp += count;595 s = src;596 s += count;597 while (count--)598 *--tmp = *--s;599 }600 return dest;601 }602 EXPORT_SYMBOL(memmove);603 #endif
- linux内核中memcpy和memmove函数的区别和实现
- linux内核中memcpy和memmove函数的区别和实现
- linux内核中memcpy和memmove函数的区别和实现
- Linux内核中memcpy和memmove函数的区别和实现
- linux内核中memcpy和memmove函数的区别和实现
- memcpy和memmove函数的区别和实现
- memcpy函数和memmove函数的模拟实现与区别
- memcpy函数和memmove函数的区别
- memmove和memcpy函数的区别及实现
- memcpy和memmove的区别与实现
- memcpy和memmove的区别与实现
- memcpy和memmove的区别与实现
- memcpy和memmove函数的实现
- memcpy和memmove函数的实现
- memcpy和memmove的函数内部实现
- memcpy memmove区别和实现
- memcpy memmove区别和实现
- memcpy memmove区别和实现
- GoldenDict辞典配置
- 最小生成树算法
- 网易有道笔试题
- PowerDesign--用例属性表实现类标签
- 如何使字符串相比较时忽略后面的空格
- linux内核中memcpy和memmove函数的区别和实现
- apue.h <<UNIX 环境高级编程>> 第二版 环境配置
- 写一段JavaScript脚本列出浏览器的信息
- ubuntu 64位编译32位软件问题
- 《Unix环境高级编程》学习笔录
- android 功能强大的飞鸽源码
- 番茄工作法--使用心得(一)
- c++中直接用类的对象名加‘.’成员运算符引用操作类的私有成员数据
- 在nginx中设置socket缓冲区大小