99热99这里只有精品6国产,亚洲中文字幕在线天天更新,在线观看亚洲精品国产福利片 ,久久久久综合网

歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

C++中的內(nèi)存重疊問題

發(fā)布時間:2016-11-06 20:59  回復(fù):0  查看:2970   最后回復(fù):2016-11-06 20:59  

本文和大家分享的主要是C++中的內(nèi)存重疊的解決辦法,希望對大家學(xué)習(xí)C++有幫助,一起來看看吧。

 ?。?nbsp;內(nèi)存重疊 ,直到做到一個筆試題才知道了什么是內(nèi)存重疊。先上題目吧,是一個淘寶的筆試題,當(dāng)時有點(diǎn)懵,不知道這個名詞是啥子意思。

  . 題目:補(bǔ)充下面函數(shù)代碼:

  如果兩段內(nèi)存重疊,用memcpy函數(shù)可能會導(dǎo)致行為未定義。 而memmove函數(shù)能夠避免這種問題,下面是一種實(shí)現(xiàn)方式,請補(bǔ)充代碼。

  .

  #include using namespace std;voidmemmove(void* str1,const void* str2,size_t n){

  char* pStr1= (char*) str1;

  const char* pStr2=(const char*)str2;

  if ( ) {

  for(size_t i=0;i!=n;++i){

  *(pStr1++)=*(pStr2++);

  }

  }

  else{

  pStr1+=n-1;

  pStr2+=n-1;

  for(size_t i=0;i!=n;++i){

  *(pStr1--)=*(pStr2--);

  }

  }

  return ( );

  }

  在上面的兩個括號中插入對應(yīng)的內(nèi)容

  答案:pstr1<pstr2 str1

 ?。?/span>

  在這里我理解的內(nèi)存重疊大致上應(yīng)該是在strcpy以及memcpy等內(nèi)存拷貝函數(shù)出現(xiàn)的問題。strcpy函數(shù)內(nèi)存重疊可能會使程序崩潰,這里我先講一個比較簡單的例子來看一下。

  .

 ?。?/span>

  #include #include #include int main(){

  char *p = NULL;

  p = (char *)malloc(10);

  memcpy(p,"1234679",strlen("1246789"));

  printf("before p = %s/n", p);

  strcpy(p+1,p);//這重疊了

  printf("after p = %s/n", p);

  free(p);

  }

 ?。?/span>

  上面的這個例子中發(fā)生了內(nèi)存重疊問題,這就導(dǎo)致了拷貝發(fā)生了異常,不會拷貝一樣的數(shù)據(jù)。我跑這個代碼的時候居然沒有報(bào)錯,程序也沒炸,我也就有點(diǎn)好奇了。按理來memcpy,strcpy這兩個函數(shù)沒有對內(nèi)存重疊進(jìn)行處理。使用這兩個函數(shù)的時候只有程序員自己保證源地址與目標(biāo)地址內(nèi)存不重疊。所以當(dāng)會發(fā)生內(nèi)存重疊的時候最好使用memmov函數(shù)進(jìn)行內(nèi)存拷貝。

 ?。?/span>

  自己查了一些資料,原來memcpy有一個長度參數(shù),只拷貝cnt個字節(jié)就結(jié)束了,所以會得到正確的結(jié)果,但是strcpy函數(shù)知道拷貝到\\0這個標(biāo)志符才會結(jié)束,所以就會導(dǎo)致程序崩潰了。

 ?。?/span>

 ?。?nbsp;memcpymemmov函數(shù)原型和區(qū)別

 ?。?/span>

  1.memmove

 ?。?/span>

  函數(shù)原型:void *memmove(void *dest, const void *source, size_t count)

 ?。?/span>

  返回值說明:返回指向destvoid *指針

 ?。?/span>

  參數(shù)說明:dest,source分別為目標(biāo)串和源串的首地址。count為要移動的字符的個數(shù)

 ?。?/span>

  函數(shù)說明:memmove用于從source拷貝count個字符到dest,如果目標(biāo)區(qū)域和源區(qū)域有重疊的話,memmove能夠保證源串在被覆蓋之前將重疊區(qū)域的字節(jié)拷貝到目標(biāo)區(qū)域中。

 ?。?/span>

  .

  2.memcpy

 ?。?/span>

  函數(shù)原型:void *memcpy(void *dest, const void *source, size_t count);

  .

  返回值說明:返回指向destvoid *指針

 ?。?/span>

  函數(shù)說明:memcpy功能和memmove相同,但是memcpydestsource中的區(qū)域不能重疊,否則會出現(xiàn)未知結(jié)果。

  .

 ?。?nbsp;實(shí)現(xiàn)一個memmov函數(shù)

  .

  #include #include using namespace std;

  void *memmove(void * dst, const void *src, size_t count){

  //特殊情況錯誤處理

  if (src == NULL || dst == NULL)

  return NULL;

  unsigned char *pdst = (unsigned char *)dst;

  const unsigned char *psrc = (const unsigned char *)src;

  //判斷內(nèi)存是否重疊

  bool flag1 = (pdst >= psrc && pdst < psrc + count);

  bool flag2 = (psrc >= pdst && psrc < pdst + count);

  //上面兩個標(biāo)志其中有一個成立,保證內(nèi)存并不是重疊的,與拷貝的長度有關(guān)

  if (flag1 || flag2){//內(nèi)存重疊

  //倒序拷貝

  while (count){

  *(pdst + count - 1) = *(psrc + count - 1);

  count--;

  }

  }

  else{//不重疊

  while (count--){

  *pdst = *psrc;

  pdst++;

  psrc++;

  }

  }

  return dst;

  }

  int main(){

  //內(nèi)存重疊的情況

  char str[] = "hello world";

  memmove(str + 3, str, 8);

  cout<<"memmove result is :"<<str<<endl;

  //內(nèi)存不重疊

  char str2[] = "hello world";

  char str3[] = "you are ";

  memmove(str2, str3, 8);

  cout<<"memmove result is :"<<str2<<endl;

  }

 ?。?nbsp;實(shí)現(xiàn)思路就是要去判斷是否內(nèi)存重疊,重疊的話就倒序的拷貝,非重疊的話就從前往后拷貝就行了。這個例子也很好的解釋了前面的那個題目的情況。其實(shí)前面的那個情況還可以用一個圖片來解釋。

C++中的內(nèi)存重疊問題 

  . 這張圖片就是這兩種情況的實(shí)現(xiàn)。

 

文章來源:博客園

您還未登錄,請先登錄

熱門帖子

最新帖子

?