Linux内核中memcpy和memmove函数的差异和实现
发布时间:2021-11-21 17:02:13 所属栏目:PHP教程 来源:互联网
导读:Kernel version:2.6.32 CPU architecture:ARM memcpy是把src指向的对象中的size个字符拷贝到dest所指向的对象中,返回指向结果对象的指针. memmove也是把src指向的对象中的size个字符拷贝到dest所指向的对象中,返回指向结果对象的指针,但这两个函数在处理内
Kernel version:2.6.32 CPU architecture:ARM •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 ![]() (编辑:应用网_丽江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |