<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > linux內(nèi)核中memcpy和memmove函數(shù)的區(qū)別和實(shí)現(xiàn)

          linux內(nèi)核中memcpy和memmove函數(shù)的區(qū)別和實(shí)現(xiàn)

          作者: 時(shí)間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
          Kernel version:2.6.32

          CPU architecture:ARM

          本文引用地址:http://www.ex-cimer.com/article/201611/320009.htm

          Author:ce123(http://blog.csdn.net/ce123)

          • memcpy是把src指向的對象中的size個(gè)字符拷貝到dest所指向的對象中,返回指向結(jié)果對象的指針.
          • memmove也是把src指向的對象中的size個(gè)字符拷貝到dest所指向的對象中,返回指向結(jié)果對象的指針,但這兩個(gè)函數(shù)在處理內(nèi)存區(qū)域重疊的方式不同.
          注意memmove這個(gè)函數(shù)名稱中有"move"這個(gè)單詞,而實(shí)際上src處的數(shù)據(jù)仍然還在,并沒有真的被"移動"了!這個(gè)函數(shù)名稱有它的歷史原因,是因?yàn)橛辛薽emcpy函數(shù)后,發(fā)現(xiàn)這個(gè)函數(shù)有問題,又發(fā)明了另一個(gè)沒有問題的memcpy函數(shù),但為了爆出兼容性依然保留了memcpy函數(shù),而將新版本的memcpy函數(shù)改名為memmove函數(shù).

          內(nèi)存重疊問題是指目的地址的內(nèi)存空間的首地址,包含在源內(nèi)存空間中,這兩段內(nèi)存空間有了交集,因而在使用memcpy進(jìn)行內(nèi)存復(fù)制操作時(shí),這段重疊的內(nèi)存空間會被破壞.這種情況在應(yīng)用程序級代碼中一般不會出現(xiàn)的,而在驅(qū)動或內(nèi)核級代碼中要十分小心,盡量使用memmove函數(shù).

          memcpy對內(nèi)存空間有要求的,dest和src所指向的內(nèi)存空間不能重疊,否則復(fù)制的數(shù)據(jù)是錯(cuò)誤的.下面具體講解一下這個(gè)錯(cuò)誤是如何產(chǎn)生的.

          如果內(nèi)存空間布局入下圖所示:

          src所指向的內(nèi)存空間后面部分?jǐn)?shù)據(jù)被新拷貝的數(shù)據(jù)給覆蓋了(也就是dest<=src+size).所以拷貝到最后,原來的數(shù)據(jù)肯定不是原來的數(shù)據(jù),拷貝的數(shù)據(jù)也不是想要的數(shù)據(jù),使用memcpy函數(shù)可以得到錯(cuò)誤的結(jié)果.

          再者,如果內(nèi)存空間布局入下圖所示:

          雖然原來的數(shù)據(jù)不再是原來的數(shù)據(jù)(dest+size>=src),但拷貝的數(shù)據(jù)是原來的數(shù)據(jù),使用memcpy函數(shù)可以得到正確的結(jié)果.因此,在使用memcpy這個(gè)函數(shù)之前,還需要做一個(gè)判斷,如果dest<=src你才能使用這個(gè)函數(shù)不過完全沒有必要,你直接使用memmove函數(shù)就可以了.memmove在拷貝之前就做了一個(gè)判斷,如果dest <= src,就按照memcpy的思路拷貝,如果dest>src怎么辦呢,看函數(shù),它是從后面往前拷貝,這樣就能正確拷貝數(shù)據(jù)了.根據(jù)上面的分析,理解下面的代碼應(yīng)該是一件很容易的事情.

          [plain]view plaincopy
          print?
          1. 551#ifndef__HAVE_ARCH_MEMCPY
          2. 552/**
          3. 553*memcpy-Copyoneareaofmemorytoanother
          4. 554*@dest:Wheretocopyto
          5. 555*@src:Wheretocopyfrom
          6. 556*@count:Thesizeofthearea.
          7. 557*
          8. 558*YoushouldnotusethisfunctiontoaccessIOspace,usememcpy_toio()
          9. 559*ormemcpy_fromio()instead.
          10. 560*/
          11. 561void*memcpy(void*dest,constvoid*src,size_tcount)
          12. 562{
          13. 563char*tmp=dest;
          14. 564constchar*s=src;
          15. 565
          16. 566while(count--)
          17. 567*tmp++=*s++;
          18. 568returndest;
          19. 569}
          20. 570EXPORT_SYMBOL(memcpy);
          21. 571#endif
          22. 572
          23. 573#ifndef__HAVE_ARCH_MEMMOVE
          24. 574/**
          25. 575*memmove-Copyoneareaofmemorytoanother
          26. 576*@dest:Wheretocopyto
          27. 577*@src:Wheretocopyfrom
          28. 578*@count:Thesizeofthearea.
          29. 579*
          30. 580*Unlikememcpy(),memmove()copeswithoverlappingareas.
          31. 581*/
          32. 582void*memmove(void*dest,constvoid*src,size_tcount)
          33. 583{
          34. 584char*tmp;
          35. 585constchar*s;
          36. 586
          37. 587if(dest<=src){
          38. 588tmp=dest;
          39. 589s=src;
          40. 590while(count--)
          41. 591*tmp++=*s++;
          42. 592}else{
          43. 593tmp=dest;
          44. 594tmp+=count;
          45. 595s=src;
          46. 596s+=count;
          47. 597while(count--)
          48. 598*--tmp=*--s;
          49. 599}
          50. 600returndest;
          51. 601}
          52. 602EXPORT_SYMBOL(memmove);
          53. 603#endif



          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();