国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C++ > 正文

C++中memcpy和memmove的區(qū)別總結(jié)

2020-01-26 15:15:23
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

變態(tài)的命名

我們?cè)趯?xiě)程序時(shí),一般講究見(jiàn)到變量的命名,就能讓別人基本知道該變量的含義。memcpy內(nèi)存拷貝,沒(méi)有問(wèn)題;memmove,內(nèi)存移動(dòng)?錯(cuò),如果這樣理解的話(huà),那么這篇文章你就必須要好好看看了,memmove還是內(nèi)存拷貝。那么既然memcpy和memmove二者都是內(nèi)存拷貝,那二者究竟有什么區(qū)別呢?

先說(shuō)memcpy

你有沒(méi)有好好的參加過(guò)一場(chǎng)C++筆試。讓你寫(xiě)出memcpy的實(shí)現(xiàn),這是多么常見(jiàn)的筆試題啊。現(xiàn)在,拿起你的演算紙和筆;是的,是筆和紙,不是讓你在你的IDE上寫(xiě)。寫(xiě)不出來(lái)?看下面吧:

復(fù)制代碼 代碼如下:

void *mymemcpy(void *dest, const void *src, size_t count)
{
    assert(dest != NULL || src != NULL);
   
    char *tmp = (char *)dest;
    char *p = (char *)src;
 
    while (count--)
    {
        *tmp++ = *p++;
    }
    return dest;
}

memcpy的實(shí)現(xiàn)很簡(jiǎn)單,一般在筆試時(shí),出現(xiàn)寫(xiě)源碼的題目,無(wú)非就是需要注意以下幾點(diǎn):

1.確定函數(shù)原型;
2.判斷參數(shù)合法性;
3.邏輯實(shí)現(xiàn)(考慮各種情況,統(tǒng)稱(chēng)邏輯實(shí)現(xiàn));
4.錯(cuò)誤處理。

當(dāng)然了,我的這個(gè)沒(méi)有錯(cuò)誤處理,也不需要錯(cuò)誤處理。上面,我寫(xiě)出了memcpy的實(shí)現(xiàn)源碼,實(shí)現(xiàn)原理如下圖所示:

這樣下去,上面的代碼會(huì)運(yùn)行的很好,如果出現(xiàn)下面的情況呢?

i、n、k的內(nèi)存和J、e、l的內(nèi)存地址重合了,現(xiàn)在再使用上面的代碼進(jìn)行copy時(shí),會(huì)出現(xiàn)什么問(wèn)題呢?你有沒(méi)有想過(guò)這個(gè)問(wèn)題。如果沒(méi)有,那就現(xiàn)在想想,不急著閱讀下面的內(nèi)容。

然后,我再留一個(gè)問(wèn)題,上面的代碼中,為什么都需要將void *轉(zhuǎn)換成char *呢?比如:

復(fù)制代碼 代碼如下:

char *tmp = (char *)dest;

可以留言回答哦。

再說(shuō)memmove

memmove也是用來(lái)實(shí)現(xiàn)內(nèi)存的直接拷貝的。說(shuō)起這個(gè)命名,我個(gè)人覺(jué)的多少還是有點(diǎn)坑的。既然memmove也是用來(lái)內(nèi)存數(shù)據(jù)移動(dòng)的,那就先來(lái)看看memmove的實(shí)現(xiàn)源碼。

復(fù)制代碼 代碼如下:

void *mymemmove(void *dest, const void *src, size_t count)
{
    assert(dest != NULL || src != NULL)
 
    if (dst < src)
    {
        char *p = (char *)dest;
        char *q = (char *)src;
        while (count--)
        {
            *p++ = *q++;
        }
    }
    else
    {
        char *p = (char *)dest + count;
        char *q = (char *)src + count;
        while (count--)
        {
            *--p = *--q;
        }
    }
 
    return dest;
}

從源碼看,memmove的確比memcpy復(fù)雜一些;再仔細(xì)一看,多了些什么?哦,多了一個(gè)else分支,而正是這個(gè)else分支,就處理了當(dāng)src和dest的內(nèi)存重合的問(wèn)題。

memcpy和memmove的比較

從實(shí)現(xiàn)源碼中的確能看出一些貓膩,當(dāng)出現(xiàn)了src和dest的內(nèi)存有重合的時(shí)機(jī)時(shí),memmove的處理規(guī)則是從后往前進(jìn)行copy。當(dāng)然了,重合的問(wèn)題,需要考慮的以下兩種場(chǎng)合。

如圖所示,當(dāng)出現(xiàn)(1)對(duì)應(yīng)的情況時(shí),就需要先從src的頭部開(kāi)始復(fù)制;也就是memmove源碼中的if分支,這部分源碼和memcpy的實(shí)現(xiàn)是一致的;當(dāng)出現(xiàn)(2)對(duì)應(yīng)的情況時(shí),就需要先從src的尾部開(kāi)始復(fù)制,防止出現(xiàn)了覆蓋現(xiàn)象。這就是memmove比memcpy多的一個(gè)考慮點(diǎn),所以說(shuō),在實(shí)際使用時(shí),使用memmove是比memcpy更安全的。

總結(jié)

總結(jié)到了這里,我覺(jué)的我已經(jīng)把問(wèn)題說(shuō)清楚了。你說(shuō)呢?如果你還有什么好的想法,歡迎你和我分享。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 道孚县| 罗山县| 秀山| 衡东县| 白河县| 甘南县| 靖远县| 新建县| 安丘市| 乌恰县| 云浮市| 龙口市| 定南县| 辽中县| 东莞市| 长兴县| 聂荣县| 常宁市| 峨边| 凭祥市| 孝感市| 会同县| 无棣县| 芒康县| 聂拉木县| 阿拉善左旗| 武乡县| 奉新县| 孝义市| 乐安县| 荆门市| 西青区| 云梦县| 嘉定区| 陇川县| 泰来县| 小金县| 宁陕县| 承德县| 永年县| 遵化市|