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所指向的对象中,返回指向结果对象的指针,但这两个函数在处理内存区域重叠的方式不同.
注意memmove这个函数名称中有"move"这个单词,而实际上src处的数据仍然还在,并没有真的被"移动"了!这个函数名称有它的历史原因,是因为有了memcpy函数后,发现这个函数有问题,又发明了另一个没有问题的memcpy函数,但为了爆出兼容性依然保留了memcpy函数,而将新版本的memcpy函数改名为memmove函数.
内存重叠问题是指目的地址的内存空间的首地址,包含在源内存空间中,这两段内存空间有了交集,因而在使用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_MEMCPY
552 /**
553 * memcpy - Copy one area of memory to another
554 * @dest: Where to copy to
555 * @src: Where to copy from
556 * @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 #endif
572
573 #ifndef __HAVE_ARCH_MEMMOVE
574 /**
575 * memmove - Copy one area of memory to another
576 * @dest: Where to copy to
577 * @src: Where to copy from
578 * @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
分享到:
相关推荐
那么既然memcpy和memmove二者都是内存拷贝,那二者究竟有什么区别呢? 先说memcpy 你有没有好好的参加过一场C++笔试。让你写出memcpy的实现,这是多么常见的笔试题啊。现在,拿起你的演算纸和笔;是的,是笔和纸,...
常用函数的实现strcpy,memcpy,memmove,strcat,strcmp原型
今天看到书上降到memcpy和memmove的区别才突然发现原来两者之间有如此区别,以前只知道这两个函数是 实现同样的功能,没有接触到其不同。 memcpy和memmove在MSDN的定义如下: 从两者的声明来看的确没有区别,我们来...
不调用C库函数实现memmove-memcpy函数功能。
c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。 void* memcpy(void* destination, const void* source, size_t num); void*...
memcpy: 头文件,函数原型,函数功能,函数返回值,说明
linux内核源码:memcpy,对比这个就发现了自己的不足,memcpy真能考验程序员的编程技能与逻辑思维
。。。
1.7 itoa函数和atoi函数 1.8 strcmp函数实现 1.9 strcpy函数实现 1.10 memcpy函数实现 1.11 memcpy和memmove函数的实现 1.12 strcat函数实现 1.13 使用库函数atoi,将char *→int 1.14 使用库函数itoa,将int→...
一个使用memcpy的实现版本,考虑内存重叠以及效率
memcpy函数的实现代码,简述了memcpy函数的实现,自己编写memcpy函数
。虽然因为硬件限制没有达到AMD文档中所说memcpy函数300%的性能提升,但在我机器上实测也有%175-%200的明显性能提升(此数据可能根据机器情况不同)。
memcpy函数c语言实现代码
1.source和destin所指内存区域不能重叠,函数返回指向destin的指针。 2.与strcpy相比,memcpy并不是遇到''结束,而是一定会拷贝完n个字节。 memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型
memcpy 和strcpy 的区别
用于了解安全函数strcpy_s、strncpy_s、snprintf_s、memcpy_s
C语言memccpy()函数:复制内存中的内容 头文件: #include 定义函数: void * memccpy(void *dest, const void * src, int c, size_t n); 函数说明:memccpy()用来拷贝src 所指的内存内容前n 个字节到dest 所指...
C语言常见的函数速查 字符串函数 bcmp bcopy bzero memccpy memchr memcmp memcpy memicmp memmove memset movmem setmem stpcpy strcat strchr strcmp strcmpi strcpy strcspn strdup ...