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

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

C++基礎(chǔ)教程之指針拷貝詳解

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

C++基礎(chǔ)教程之指針拷貝詳解

 指針是編程人員的夢(mèng)魘,對(duì)C語(yǔ)言的開(kāi)發(fā)者是如此,對(duì)C++的開(kāi)發(fā)者也是如此。特別是在C++中,如果不注意處理類中的指針,非常容易出問(wèn)題。如果朋友們不相信可以看看下面的代碼:

class data {  int* value; public:  data(int num){  if(num > 0)   value = (int*)malloc(sizeof(int)* num);  }   ~data(){  if(value)   free(value);  } };  void process() {  data m(10);  data p = m; } 

    上面的這段問(wèn)題有沒(méi)有什么問(wèn)題?大家可以自己先用筆在草稿紙上面畫(huà)一畫(huà)。然后上機(jī)用實(shí)際環(huán)境驗(yàn)證一下。果不其然,系統(tǒng)提示內(nèi)存發(fā)生了錯(cuò)誤。為什么呢?就是因?yàn)閮?nèi)存發(fā)生了兩次釋放。我們看以看一下process的匯編代碼:

21: data m(10); 0040105D push 0Ah 0040105F lea  ecx,[ebp-10h] 00401062 call @ILT+15(data::data) (00401014) 00401067 mov  dword ptr [ebp-4],0 22: data p = m; 0040106E mov  eax,dword ptr [ebp-10h] 00401071 mov  dword ptr [ebp-14h],eax 23: } 00401074 lea  ecx,[ebp-14h] 00401077 call @ILT+5(data::~data) (0040100a) 0040107C mov  dword ptr [ebp-4],0FFFFFFFFh 00401083 lea  ecx,[ebp-10h] 00401086 call @ILT+5(data::~data) (0040100a) 0040108B mov  ecx,dword ptr [ebp-0Ch] 0040108E mov  dword ptr fs:[0],ecx 00401095 pop  edi 00401096 pop  esi 00401097 pop  ebx 00401098 add  esp,54h 0040109B cmp  ebp,esp 0040109D call __chkesp (004015b0) 004010A2 mov  esp,ebp 004010A4 pop  ebp 004010A5 ret 

    21行: data調(diào)用構(gòu)造函數(shù),分配內(nèi)存給value

    22行: 這里我們發(fā)現(xiàn)程序進(jìn)行內(nèi)存拷貝,那么表示m變量value的數(shù)值和p變量中value的數(shù)值是一樣的

   23行:這里函數(shù)即將結(jié)束,所以系統(tǒng)調(diào)用m和p的析構(gòu)函數(shù),第一次析構(gòu)的時(shí)候value指向的內(nèi)存被釋放,第二次析構(gòu)的時(shí)候由于p變量value的數(shù)值非0,所以也需要釋放內(nèi)存,當(dāng)然也需要進(jìn)行析構(gòu)處理,但是此時(shí)內(nèi)存已經(jīng)釋放了,所以內(nèi)存進(jìn)行了二次釋放,系統(tǒng)報(bào)錯(cuò)。 

   經(jīng)過(guò)上面的研究,我們發(fā)現(xiàn)了問(wèn)題和原因,那么應(yīng)該怎么解決呢?既然問(wèn)題是在拷貝函數(shù)這里,那么就要對(duì)拷貝函數(shù)進(jìn)行特殊處理。目前就我個(gè)人理解,有兩個(gè)方法供大家選擇:

    (1)對(duì)拷貝構(gòu)造函數(shù)進(jìn)行private處理,這樣一旦出現(xiàn)了拷貝操作,編譯器就會(huì)提示出錯(cuò)。

class data {  int* value;  data(const data&) ; public:  data(int num){  if(num > 0)   value = (int*)malloc(sizeof(int)* num);  }   ~data(){  if(value)   free(value);  } }; 

   (2)編寫(xiě)拷貝構(gòu)造函數(shù),進(jìn)行內(nèi)存深復(fù)制

class data {   int* value;   int number; public:   data(int num){     if(num > 0)       value = (int*)malloc(sizeof(int)* num);     number = num;   }    data(const data& d){     if(NULL != d.get_ptr())       value = (int*) malloc(sizeof(int)* d.get_number());     number = d.get_number();     memmove(value, d.get_ptr(), sizeof(int)* number);   }    ~data(){     if(value)       free(value);   }    int* get_ptr() const{ return value;}   int get_number() const {return number;} }; 

  我們看到,經(jīng)過(guò)拷貝構(gòu)造函數(shù)的定義后,原來(lái)的process函數(shù)解可以正常編譯通過(guò),沒(méi)有問(wèn)題。

 感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 铜陵市| 茶陵县| 阳信县| 东光县| 余姚市| 浦北县| 乌兰浩特市| 佳木斯市| 华坪县| 湟中县| 齐河县| 辽源市| 柳江县| 伊宁县| 太仆寺旗| 三门峡市| 肥东县| 太仓市| 麻阳| 巴林左旗| 南投市| 珲春市| 明星| 丰台区| 稻城县| 凤台县| 惠东县| 富裕县| 荆门市| 洛隆县| 葵青区| 威宁| 阜新| 墨玉县| 思南县| 兴国县| 吴川市| 兴仁县| 习水县| 张家川| 高尔夫|