在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

memcpy和memmove的區別是什么

汽車電子技術 ? 來源: wenzi嵌入式軟件 ? 作者:wenzid ? 2023-01-20 16:55 ? 次閱讀

基本概念闡述

memcpymemmove都是 C 語言的庫函數,相比于 strcpystrncpy只能針對于字符類型的數組(),這兩個函數可以拷貝其他類型的數組,對于 memcpymemmove的區別是什么呢?這里,在 Linux 里通過 man命令查看兩個函數的區別,查詢的結果如下所示,首先是 memcpy函數的闡述。

圖片

image-20210729214558247

通過上述信息,可以知道,函數原型是:

void *memcpy(void *dest, const void *src, size_t n);

這個函數的功能如上面所說,就是復制src存儲區域 n個字節到dest區域,并且srcdest的內存區域不能夠重疊。

緊接著來看memmove函數,同樣的,來看Linux里的幫助手冊:

圖片

image-20210729234529864

通過上述信息,可以知道,對于memmove的函數原型是:

void *memmove(void *dest, const void *src, size_t n);

具體函數是什么意思呢?通過上圖中的DESCRIPTION可以看到:

memmove() 函數將 n 個字節從內存區域 src 復制到內存區域 dest, 但是相比于memcpy函數不同的是,他的內存區域可能會重疊:復制的過程就好比是將 src 中的字節首先被復制到一個不重疊的臨時數組中srcdest中,然后將字節從臨時數組復制到 dest

實現 memcpy 和 memmove及原理介紹

關于前面所敘述的內存重疊的情況,會出現哪些問題呢?在論述這個問題之前,我們先來自己實現 memcpy 和 memmove 函數,當然自己實現的大多數情況是沒有庫實現的那么嚴謹和完備的。首先是memcpy函數的實現:

void *memcpy(void *dest, const void *src, size_t count)  
{  
    if(dest == NULL || src == NULL || count <= 0)  return NULL;  
    char *d = (char *)dest;  
    char *s = (char *)src;  
    while(count--)  
    {  
        *d++ = *s++;  
    }  
    return dest;  
}

代碼很容易理解,就不在這里進行贅述了,其中,有一點也是筆者自己以前容易遺忘的一點,就是函數入口處對參數進行檢查,不然會發生意想不到的錯誤。

接下來就是 memmove函數的實現:

void *memmove(void *dest, const void *src, size_t count)  
{  
    if(dest == NULL || src == NULL || count <= 0)  return NULL;  
    if(dest < src)  
    {  
        char *d = (char *)dest;  
        char *s = (char *)src;  
        while (count--)  
        {  
            *d++ = *s++;  
        }  
    }  
    else  
    {  
        char *d = (char *)dest + count;  
        char *s = (char *)src + count;  
        while (count--)  
        {  
            *--d = *--s;  
        }  
    }      
    return dest;  
}

memmove 函數要相比于 memcpy函數的實現要復雜一點點:分成了目的地址在前還是在后兩種情況,如果是目的地址在前,那么就必須將src地址所在的字符串從前往后拷貝,反之,則必須將src所在的字符串從后往前拷貝。

如何解釋這一原因呢,我們從一個例子說起,下面是對應的代碼:

int main(int argc, char **argv) 
{
    int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
    int i = 0;
    my_memcpy(arr + 2, arr, 20);

    for (i = 0; i < 10; i++) 
    {
        printf("%d ", arr[i]);
    }

    return 0;
}

可以看到代碼所實現的功能是,將arr數組中12345拷貝到 34567所在的地址中去,按照這樣一個思路,因該輸出的是:

1 2 1 2 3 4 5 8 9 10

但是程序運行后輸出的是:

1 2 1 2 1 2 1 8 9 10

這是為什么呢?筆者這里來圖解一下:

圖片

image-20210730003005350

首先,將src地址的值賦值給dest,然后指針后移動,繼續下一次的賦值,此時數據就發生了變化,如下圖所示:

圖片

image-20210730003025398

可以看到,此時 3 的位置變成了 1,繼續移動指針,也就有了如下的變化:

圖片

image-20210730003207597

我們依據此原理,最后再移動三次指針,也就是如下所示的變化:

圖片

image-20210730004153026

最終也就得到了上述的結果。

這種情況也就是dest在后,然后src在前的一種情況,如果是從前往后拷貝的話,也就會造成上述的問題,而解決的辦法就是從后往前拷貝,具體的過程,也如下圖所示:

圖片

image-20210730005452356

可見,如果是此時 dest的地址在src的后面,那么就需要從后往前復制,這樣才不會導致數據覆蓋掉。

額外注意的一點,上文也提到了,就是說,對于 memmove 也不是一概而論的,如果是 dest的地址在前面,那么也還是需要從前往后復制才行。

至此,關于 memmove和 memcpy 的內容就敘述完啦~

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7608

    瀏覽量

    137084
  • memcpy
    +關注

    關注

    0

    文章

    9

    瀏覽量

    2834
  • strcpy
    +關注

    關注

    0

    文章

    5

    瀏覽量

    1212
收藏 人收藏

    評論

    相關推薦

    高效率的內存拷貝函數memcpy

    memcpy是memory copy的縮寫,意為內存復制,在寫C語言程序的時候,我們常常會用到它。
    發表于 11-08 09:48 ?8496次閱讀

    C語言中memmove函數的使用

    在C語言編程中,內存操作是不可或缺的一部分,而 memmove 函數是其中一個重要的工具。本文將介紹 memmove 函數的應用場景以及提供詳細的示例代碼,幫助您更好地理解如何使用這個函數。我們將探討三個主要的應用場景,分別是
    發表于 09-13 09:17 ?1574次閱讀

    Memset、Memcpy、Strcpy 的作用和區別(轉)

    使用printf("%s\n",dest);時 輸出遇到'\0'時停此輸出.所以會輸出: Hello (4) 三者區別memset主要應用是初始化某個內存空間。memcpy是用于copy源
    發表于 01-19 11:57

    GPU和CPU的區別是什么

    GPU是如何工作的GPU與DSP區別GPU和CPU的區別是什么
    發表于 01-05 06:15

    memcpymemmove有哪些區別

    memcpy指的是什么?memmove有何作用?
    發表于 12-20 06:19

    strcpy和memcpy區別是什么

    –strcpy和memcpy區別?(1)復制的內容不同。strcpy只能復制字符串,而memcpy可以復制任意內容,例如字符數組、整型、結構體、類等。(2)復制的方法不同。strcpy不需要指定
    發表于 12-21 06:40

    求助!如何才能使memcpy完全使用rt_memcpy

    rt_memcpy_v6.o(.text) refers to rt_memcpy_w.o(.text) for __aeabi_memcpy4 rt_memmove_v6.o(.t
    發表于 04-07 09:28

    怎樣去解決memcpy aeabi_memcpy aeabi_memcpy4問題呢?

    ) for __aeabi_memcpy4rt_memmove_v6.o(.text) refers to rt_memcpy_v6.o(.text) for __aeabi_memcpyrt_memmove_v6.o(.tex
    發表于 02-08 11:20

    memcpy怎么用_memcpy用法總結

    memcpy指的是c和c++使用的內存拷貝函數,memcpy函數的功能是從源src所指的內存地址的起始位置開始拷貝n個字節到目標dest所指的內存地址的起始位置中。從源src所指的內存地址的起始位置開始拷貝n個字節到目標dest所指的內存地址的起始位置中。
    發表于 11-28 15:56 ?4.7w次閱讀
    <b class='flag-5'>memcpy</b>怎么用_<b class='flag-5'>memcpy</b>用法總結

    C語言模擬實現memcpy函數

    memcpy指的是c和c++使用的內存拷貝函數,memcpy函數的功能是從源src所指的內存地址的起始位置開始拷貝n個字節到目標dest所指的內存地址的起始位置中。
    的頭像 發表于 06-29 17:29 ?2511次閱讀
    C語言模擬實現<b class='flag-5'>memcpy</b>函數

    C語言模擬實現memmove函數

    memmove用于從src拷貝count個字節到dest,如果目標區域和源區域有重疊的話,memmove能夠保證源串在被覆蓋之前將重疊區域的字節拷貝到目標區域中。但復制后src內容會被更改。但是當目標區域與源區域沒有重疊則和memcpy
    的頭像 發表于 06-29 17:53 ?1785次閱讀
    C語言模擬實現<b class='flag-5'>memmove</b>函數

    memcpy函數實現及其優化

    函數原型void * memcpy ( void * destination, const void * source, size_t num );
    發表于 12-09 14:25 ?2712次閱讀

    cob光源和led的區別是什么

    顯示屏中,cob光源和led光源的區別是什么?
    的頭像 發表于 12-24 10:18 ?9444次閱讀

    LED和OLED的區別是什么

    LED和OLED的區別是什么?
    的頭像 發表于 01-14 18:30 ?1.7w次閱讀

    C語言庫memcpymemmove區別分析

    memcpymemmove都是 C 語言的庫函數,相比于 strcpy和 strncpy只能針對于字符類型的數組(),這兩個函數可以拷貝其他類型的數組,對于 memcpymemmove
    發表于 09-19 12:19 ?2074次閱讀
    主站蜘蛛池模板: 国产aa| q2002韩国理论| 97影院理论在线观看| 中日韩一级片| 天天骑天天射| 久久天天躁狠狠躁夜夜免费观看 | 香蕉久久精品| 操碰人人| brazzersvideosex欧美最| 亚洲操操操| 好色成人网| 国产 日韩 欧美 高清| 在线免费看片| 99色视频在线| 天天碰视频| 福利精品| 日本视频三区| 亚洲一区视频在线| 精品一区亚洲| 色天使在线视频| 韩国一级网站| 天天天狠天天透天天制色| 国产破苞合集 magnet| 亚洲国产一区二区三区a毛片| 在线视频这里只有精品| 日韩色网| 高清人妖shemale japan| 色天天网| 4438x全国免费| 亚洲伦理一区二区三区| 曰本毛片| 日本福利网址| 俺来色| 狠狠的干狠狠的操| 日本一区二区三区欧美在线观看| 香蕉视频啪啪| 黄色视屏在线免费观看| 天天操好逼| 在线观看亚洲一区二区| 无码一区二区三区视频| 午夜免费免费啪视频观看|