日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

c语言实现memcpy

發(fā)布時(shí)間:2023/11/27 生活经验 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言实现memcpy 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

今天到I 公司去面試,面試方式比較特殊,沒(méi)有筆試,就是2 個(gè)面試官,一人一句輪番發(fā)問(wèn),涉及面很廣,涉及到操作系統(tǒng)(MMUpage out 、process/thread 、semaphore 、interrupt), OOP( 多態(tài)、design pattern) 、數(shù)據(jù)結(jié)構(gòu)( 排序、二叉查找樹(shù)) 、計(jì)算機(jī)網(wǎng)絡(luò)(OSI 5)C 語(yǔ)言(big/small endian) 、英語(yǔ)口語(yǔ)等等,問(wèn)了大約一個(gè)小時(shí)左右。

所有問(wèn)題都是口頭表述,只在紙上寫了一個(gè)memcpy 程序,用C 語(yǔ)言實(shí)現(xiàn),腦子一發(fā)蒙,既然寫成了strcpy ,真該死。

回家了查詢了一下memcpy 定義,如下:

Void *memcpy(void *dest, const void *src, unsigned int count);

查詢msdn, 發(fā)現(xiàn)Remark 如下:

memcpy copies count bytes from src to dest ; If the source and destination overlap, the behavior of memcpy is undefined. Use memmove to handle overlapping regions.

以上描述針對(duì)dest src 所指的內(nèi)存地址有重疊的情況,內(nèi)存地址重疊情況,memcpy 函數(shù)處理步驟未定,而memmove 對(duì)重疊情況給予處理;

winXP+visual c++2005 測(cè)試 memcpy 函數(shù),程序如下:

?

#include "stdafx.h"

#include <string.h>

int _tmain (int argc , _TCHAR * argv [])

{

?????? char s [16] = "aabbcc" ;

?????? char d [16] = {0};

??????

?????? memcpy (s +2, s , 4);

?????? printf ("%s" , s );

?????? return 0;

}

結(jié)果輸出 “aaaabb”, 由此可見(jiàn)windows 平臺(tái)的c 運(yùn)行時(shí)MSVCRTmemcpy 函數(shù)對(duì)重疊部分做了處理,同memmove 的實(shí)現(xiàn)。//notes: 如果重疊部分不做處理,應(yīng)該輸出”aaaaaa”

下面我們用c 語(yǔ)言來(lái)實(shí)現(xiàn)memcpy 函數(shù), 首先我們寫出不對(duì)內(nèi)存重疊的處理函數(shù),如下:

void *memcpy_no_handle_overlap (void *dest , void *src , unsigned int count )

{

?????? if ((NULL ==dest ) || (NULL ==src ))

????????????? return NULL ;

?

?????? char *d = (char *)dest ;

?????? char *s = (char *)src ;

?

?????? //Do normal (Upwards) Copy

?????? while (count -- > 0)

????????????? *d ++ = *s ++;

?????? return dest ;

}

測(cè)試程序如下:

int _tmain(int argc, _TCHAR* argv[])

{

?????? char s[16] = "aabbcc";

?????? char d[16] = {0};

??????

?????? memcpy_no_handle_overlap(s+2, s, 4);

?

?????? printf("%s", s);

?????? return 0;

}

輸出結(jié)果”aaaaaa”

下面討論處理memory overlapping 情況,如下圖:




判斷overlapping 條件如下:

If ( (dest <= src) ||??????????????? // green region 1

?? (dest >=src+count) )?????????? // green region 2

{

?????? // no memory overlapping

}

Else? // red region 3

{

?????? // there is overlapping

}

Overlapping 的處理:

我們可以看到memcpy_no_handle_overlap 函數(shù),是從低地址依次賦值到高地址;在處理overlapping 時(shí),如果我們采用同樣的方法( 低地址到高地址) ,高地址的值將會(huì)被覆蓋,所以我們應(yīng)該從高地址依次到低地址賦值,如下圖:

?

? 函數(shù)代碼如下:

void *memcpy_handle_overlap(void *dest, void *src, unsigned int count)

{

?????? if ((NULL==dest) || (NULL==src))

????????????? return NULL;

?

?????? char *d = (char *)dest;

?????? char *s = (char *)src;

?

?????? //Check for overlapping buffers:

?????? if ( (d<=s) || (d>=s+count) )

?????? {?????

????????????? //Do normal (Upwards) Copy

????????????? while (count-- > 0)

???????????????????? *d++ = *s++;

?????? }

?????? else

?????? {

????????????? //Do Downwards Copy to avoid propagation

????????????? while (count > 0)

????????????? {

???????????????????? *(d+count-1) = *(s+count-1);

???????????????????? --count;

????????????? }

?

?????? }

?

?????? return dest;

}

測(cè)試代碼:

int _tmain(int argc, _TCHAR* argv[])

{

?????? char s[16] = "aabbcc";

?????? char d[16] = {0};

??????

?????? memcpy_handle_overlap(s+2, s, 4);

?

?????? printf("%s", s);

?????? return 0;

}

輸出結(jié)果為: aaaabb

?

最后測(cè)試代碼如下:

int _tmain(int argc, _TCHAR* argv[])

{

?????? char s[16] = "aabbcc";

?????? memcpy_no_handle_overlap(s+2, s, 4);

?????? printf("memcpy(ignore memory overlapping): %s/n", s);

?

?????? strcpy(s, "aabbcc");

?????? memcpy_handle_overlap(s+2, s, 4);

?????? printf("memcpy(handle memory overlapping): %s/n", s);

?

???? strcpy(s, "aabbcc");

?????? memcpy(s+2, s, 4);

?????? printf("memcpy( MSVCRT ): %s/n", s);

?

?????? strcpy(s, "aabbcc");

?????? memmove(s+2, s, 4);

?????? printf("memmove( MSVCRT): %s/n", s);

?

?????? return 0;

}

輸出結(jié)果為:

memcpy(ignore memory overlapping): aaaaaa

memcpy(handle memory overlapping): aaaabb

memcpy( MSVCRT ): aaaabb

memmove( MSVCRT): aaaabb

總結(jié)

以上是生活随笔為你收集整理的c语言实现memcpy的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。