0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

memcpy和memmove的區(qū)別是什么

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

基本概念闡述

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

圖片

image-20210729214558247

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

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

這個(gè)函數(shù)的功能如上面所說,就是復(fù)制src存儲(chǔ)區(qū)域 n個(gè)字節(jié)到dest區(qū)域,并且srcdest的內(nèi)存區(qū)域不能夠重疊。

緊接著來看memmove函數(shù),同樣的,來看Linux里的幫助手冊(cè):

圖片

image-20210729234529864

通過上述信息,可以知道,對(duì)于memmove的函數(shù)原型是:

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

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

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

實(shí)現(xiàn) memcpy 和 memmove及原理介紹

關(guān)于前面所敘述的內(nèi)存重疊的情況,會(huì)出現(xiàn)哪些問題呢?在論述這個(gè)問題之前,我們先來自己實(shí)現(xiàn) memcpy 和 memmove 函數(shù),當(dāng)然自己實(shí)現(xiàn)的大多數(shù)情況是沒有庫實(shí)現(xiàn)的那么嚴(yán)謹(jǐn)和完備的。首先是memcpy函數(shù)的實(shí)現(xiàn):

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;  
}

代碼很容易理解,就不在這里進(jìn)行贅述了,其中,有一點(diǎn)也是筆者自己以前容易遺忘的一點(diǎn),就是函數(shù)入口處對(duì)參數(shù)進(jìn)行檢查,不然會(huì)發(fā)生意想不到的錯(cuò)誤。

接下來就是 memmove函數(shù)的實(shí)現(xiàn):

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 函數(shù)要相比于 memcpy函數(shù)的實(shí)現(xiàn)要復(fù)雜一點(diǎn)點(diǎn):分成了目的地址在前還是在后兩種情況,如果是目的地址在前,那么就必須將src地址所在的字符串從前往后拷貝,反之,則必須將src所在的字符串從后往前拷貝。

如何解釋這一原因呢,我們從一個(gè)例子說起,下面是對(duì)應(yīng)的代碼:

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;
}

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

1 2 1 2 3 4 5 8 9 10

但是程序運(yùn)行后輸出的是:

1 2 1 2 1 2 1 8 9 10

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

圖片

image-20210730003005350

首先,將src地址的值賦值給dest,然后指針后移動(dòng),繼續(xù)下一次的賦值,此時(shí)數(shù)據(jù)就發(fā)生了變化,如下圖所示:

圖片

image-20210730003025398

可以看到,此時(shí) 3 的位置變成了 1,繼續(xù)移動(dòng)指針,也就有了如下的變化:

圖片

image-20210730003207597

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

圖片

image-20210730004153026

最終也就得到了上述的結(jié)果。

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

圖片

image-20210730005452356

可見,如果是此時(shí) dest的地址在src的后面,那么就需要從后往前復(fù)制,這樣才不會(huì)導(dǎo)致數(shù)據(jù)覆蓋掉。

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

至此,關(guān)于 memmove和 memcpy 的內(nèi)容就敘述完啦~

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7575

    瀏覽量

    134022
  • memcpy
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    2810
  • strcpy
    +關(guān)注

    關(guān)注

    0

    文章

    5

    瀏覽量

    1193
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    高效率的內(nèi)存拷貝函數(shù)memcpy

    memcpy是memory copy的縮寫,意為內(nèi)存復(fù)制,在寫C語言程序的時(shí)候,我們常常會(huì)用到它。
    發(fā)表于 11-08 09:48 ?8063次閱讀

    C語言中memmove函數(shù)的使用

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

    Memset、Memcpy、Strcpy 的作用和區(qū)別(轉(zhuǎn))

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

    GPU和CPU的區(qū)別是什么

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

    memcpymemmove有哪些區(qū)別

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

    strcpy和memcpy區(qū)別是什么

    –strcpy和memcpy區(qū)別?(1)復(fù)制的內(nèi)容不同。strcpy只能復(fù)制字符串,而memcpy可以復(fù)制任意內(nèi)容,例如字符數(shù)組、整型、結(jié)構(gòu)體、類等。(2)復(fù)制的方法不同。strcpy不需要指定
    發(fā)表于 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
    發(fā)表于 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
    發(fā)表于 02-08 11:20

    memcpy怎么用_memcpy用法總結(jié)

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

    C語言模擬實(shí)現(xiàn)memcpy函數(shù)

    memcpy指的是c和c++使用的內(nèi)存拷貝函數(shù),memcpy函數(shù)的功能是從源src所指的內(nèi)存地址的起始位置開始拷貝n個(gè)字節(jié)到目標(biāo)dest所指的內(nèi)存地址的起始位置中。
    的頭像 發(fā)表于 06-29 17:29 ?2407次閱讀
    C語言模擬實(shí)現(xiàn)<b class='flag-5'>memcpy</b>函數(shù)

    C語言模擬實(shí)現(xiàn)memmove函數(shù)

    memmove用于從src拷貝count個(gè)字節(jié)到dest,如果目標(biāo)區(qū)域和源區(qū)域有重疊的話,memmove能夠保證源串在被覆蓋之前將重疊區(qū)域的字節(jié)拷貝到目標(biāo)區(qū)域中。但復(fù)制后src內(nèi)容會(huì)被更改。但是當(dāng)目標(biāo)區(qū)域與源區(qū)域沒有重疊則和memcpy
    的頭像 發(fā)表于 06-29 17:53 ?1730次閱讀
    C語言模擬實(shí)現(xiàn)<b class='flag-5'>memmove</b>函數(shù)

    memcpy函數(shù)實(shí)現(xiàn)及其優(yōu)化

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

    cob光源和led的區(qū)別是什么

    顯示屏中,cob光源和led光源的區(qū)別是什么?
    的頭像 發(fā)表于 12-24 10:18 ?8869次閱讀

    LED和OLED的區(qū)別是什么

    LED和OLED的區(qū)別是什么?
    的頭像 發(fā)表于 01-14 18:30 ?1.6w次閱讀

    C語言庫memcpymemmove區(qū)別分析

    memcpymemmove都是 C 語言的庫函數(shù),相比于 strcpy和 strncpy只能針對(duì)于字符類型的數(shù)組(),這兩個(gè)函數(shù)可以拷貝其他類型的數(shù)組,對(duì)于 memcpymemmove
    發(fā)表于 09-19 12:19 ?1837次閱讀