



下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、內(nèi)存重疊:拷貝的目的地址在源地址范圍內(nèi)。所謂內(nèi)存重疊就是拷貝的目的地址和源地址有重疊。在函數(shù)strcpy和函數(shù)memcpy都沒有對內(nèi)存重疊做處理的,使用這兩個函數(shù)的時(shí)候只有程序員自己保證源地址和目標(biāo)地址不重疊,或者使用memmove函數(shù)進(jìn)行內(nèi)存拷貝。memmove函數(shù)對內(nèi)存重疊做了處理?,F(xiàn)在來看函數(shù)strcpy原型:extern char *strcpy(char *dest,char *source);功能:把source所指由NULL結(jié)束的字符串復(fù)制到dest所指的數(shù)組中。說明:source和dest所指內(nèi)存區(qū)域不可以重疊且dest必須有足夠的空間來容納source的字符串。返回指向des
2、t的指針。重疊從兩方面考慮:(1).dest數(shù)據(jù)覆蓋了source; 如:dest(8byte) 地址:1000source(8byte) 地址:1002(2).dest所指的區(qū)域本來就是source的一部分; 如:dest(8byte) 地址:1000source(8byte) 地址:0998例如:針對第一種交叉情況情況,dst<src且dst+count>src,memcpy和memmove的結(jié)果是一樣的。請看下面的例子講解:string s = "hello world"memmove(&s0,&s5,10);舉個內(nèi)存重疊環(huán)境的例子:int
3、 main()char *p = NULL;p=(char*)malloc(100);memcpy(p,"123456789",strlen("123456789"); /會等到錯誤的結(jié)果,有一個長度參數(shù),只能拷貝cnt個/字節(jié)就結(jié)束了printf("before p =%sn",p);strcpy(p+1,p); /注意:這里重疊了,而strcpy是根據(jù)判斷原串中的'0'printf("after p =%sn",p);free(p);1.下面來看strcpy()原型寫法: 字符串拷貝.
4、;char *strcpy(char *strDest, const char *strSrc)assert(strDest!=NULL) && (strSrc !=NULL);char *address = strDest; while( (*strDest+ = * strSrc+)·1 != '/0') NULL ; return address ; 2.下面來看下memcpy函數(shù)的原型寫法:內(nèi)存拷貝void *memcpy(void *dest, const void *source, size_t co
5、unt)assert(NULL != dest) && (NULL != source);char *tmp_dest = (char *)dest;char *tmp_source = (char *)source;while(count -)/不對是否存在重疊區(qū)域進(jìn)行判斷*tmp_dest + = *tmp_source +;return dest;3.下面來看下memmove函數(shù)的原型寫法:void *memmove(void *dest, const void *source, size_t count)assert(NULL != dest) && (
6、NULL != source);char *tmp_source, *tmp_dest;tmp_source = (char *)source;tmp_dest = (char *)dest;if(dest + count<source) | (source + count) <dest)/ 如果沒有重疊區(qū)域while(count-)*tmp_dest+ = *tmp_source+;else /如果有重疊(反向拷貝)tmp_source += count - 1;tmp_dest += count - 1;while(count-)*-tmp_dest = *-tmp;retur
7、n dest;深入分析:void *memcpy(void *dst, const void *src, size_t count):void *memmove(void *dst, const void *src, size_t count);先看一個測試:#include <string.h>#include <stdio.h>int main() int a10;for(int i=0; i < 10; i+)ai = i;memcpy (&a4,a,sizeof(int)*6); /結(jié)果為:1 2 3 0 1 2 3 0 1/memcpy(&
8、;a4, a, sizeof(int)*6); /結(jié)果為:1 2 3 0 1 2 3 0 1(vc下和下面一個相同)/MemMove(&a4,a,sizeof(int)*6); /結(jié)果為:1 2 3 0 1 2 3 4 5/memmove(&a4,a,sizeof(int)*6); /結(jié)果為:1 2 3 0 1 2 3 4 5/MemMove(a,&a4,sizeof(int)*6); /結(jié)果為:5 6 7 8 9 6 7 8 9/memmove(a, &a4, sizeof(int)*6);/結(jié)果為:5 6 7 8 9 6 7 8 9/memcpy(a, &a
9、mp;a4, sizeof(int)*6); /結(jié)果為:5 6 7 8 9 6 7 8 9/MemCopy(a,&a4,sizeof(int)*6); /結(jié)果為:5 6 7 8 9 6 7 8 9for(i = 0; i < 10; i+)printf("%d ",ai);printf("/n");return 0;它們都是從src所指向的內(nèi)存中復(fù)制count個字節(jié)到dst所指內(nèi)存中,并返回dst的值。當(dāng)源內(nèi)存區(qū)域和目標(biāo)內(nèi)存區(qū)域無交叉時(shí),兩者的結(jié)果都是一樣的。但有交叉時(shí)不一樣。源內(nèi)存和目標(biāo)內(nèi)存交叉的情況有以下兩種:(左邊為低地址)即:dst
10、<=src 且 dst+count>src針對第一種交叉情況情況,dst<=src且dst+count>src,memcpy和memmove的結(jié)果是一樣的。請看下面的例子講解:int a = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9;memcpy(a, a+4, sizeof(int)*6);和memmove(a, a+4, sizeof(int)*6);結(jié)果一樣,都是:4567896789針對第二種情況,src<dst且src+count>dst,memcpy和memmove的結(jié)果是不一樣的。請看下面的例子:int a = 0, 1, 2,
11、 3, 4, 5, 6, 7, 8, 9;memcpy(a+4, a, sizeof(int)*6) 結(jié)果按照分析應(yīng)該是:0123012301但是在vs2005上運(yùn)行卻是:0123012345(有知道的,請告訴我原因)memmove(a+4, a, sizeof(int)*6) 結(jié)果是:0123012345總結(jié):1. 當(dāng) src 和 dest 所指內(nèi)存區(qū)有重疊時(shí),memmove 相對 memcpy 能提供保證:保證能將 src 所指內(nèi)存區(qū)的前 n 個字節(jié)正確的拷貝到 dest 所指內(nèi)存中;2. 當(dāng) src 地址比 dest 地址低時(shí),兩者結(jié)果一樣。換句話說,memmove 與 memcpy 的
12、區(qū)別僅僅體現(xiàn)在 dest 的頭部和 src 的尾部有重疊的情況下;綜上所述在進(jìn)行內(nèi)存重疊的考慮時(shí),strcpy,memcpy都要做一個內(nèi)存重疊的判斷:對于memcpy需要加上一個斷言:Assert(dst<=src | src+count<dst);source和dest所指內(nèi)存區(qū)域不可以重疊且dest必須有足夠的空間來容納source的字符串。返回指向dest的指針。對于strcpy需要加上一個斷言:int count = strlen(src) + 1;/src lengthAssert (dest<src | dest>(src+count)考慮了內(nèi)存重疊的內(nèi)存拷
13、貝函數(shù) memcpy ,相當(dāng)于memmove考慮內(nèi)存重疊的字符串拷貝函數(shù)strcpychar * strcpy(char *dest, const char *src) char *d = dest; /backup input char *s = src; int count = 0; assert(dest); /非空指針檢查 assert(src); if(src
14、= dest) return src; count = strlen(src) + 1;/src length if(count<=1) return 0; /empty src if(dest<src | dest>(src+count) while(count-) *d+ = *s+; else /dest 位于src+count中間, d = dest+coun
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 加盟保潔公司合同范本
- 2024年鹽城市濱??h招聘教師考試真題
- 農(nóng)村房屋共建合同范例
- 2024年梧州市龍圩區(qū)招錄公益性崗位人員考試真題
- 公司之間供貨合同范本
- 動產(chǎn)轉(zhuǎn)讓合同范本
- 2024年普洱市墨江縣教體系統(tǒng)所屬事業(yè)單位緊缺招聘考試真題
- 2024年綿陽市投資控股有限公司招聘筆試真題
- 第12課 宋元時(shí)期的都市和文化(教學(xué)設(shè)計(jì))七年級歷史下冊同步備課系列(部編版)
- 做代理合同范本
- 《ABO血型鑒定》課件
- 廣東省汕頭市潮陽區(qū)2024-2025學(xué)年高二上學(xué)期期末考試英語試題
- 計(jì)算機(jī)行業(yè)人工智能系列深度報(bào)告:deepseek研究框架-國海證券-20250214
- 李四光《看看我們的地球》原文閱讀
- 讀書分享-于永正-我怎樣教語文
- 高中語文(統(tǒng)編版)選必中冊-第二單元教材分析解讀課件
- 六年級語文下冊第五單元教材解析
- 2024年湖南高速鐵路職業(yè)技術(shù)學(xué)院單招職業(yè)技能測試題庫及答案解析
- 《大學(xué)生安全教育》課件-第一課 國家安全
- (精選)檢察院政治部副主任述職報(bào)告
- 人教版初三歷史九年級全冊思維導(dǎo)圖
評論
0/150
提交評論