語言中內(nèi)存重疊問題_第1頁
語言中內(nèi)存重疊問題_第2頁
語言中內(nèi)存重疊問題_第3頁
語言中內(nèi)存重疊問題_第4頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論