BUG現形記(二) 偷工減料的複製建構函式

2021-06-06 19:57:11 字數 2697 閱讀 1953

【課程支撐】我的 c++程式設計課程教學材料

【摘要】設計陣列類,要實現陣列類中兩個陣列相加的運算,程式卻陷入死迴圈。逐層排查,過載的加法正確,過載的賦值運算也看不出問題。跟蹤到賦值運算的實現中發現,傳遞的引數中有異常,終於找出了嫌疑犯——編制的複製建構函式偷工減料。

【閱讀提示】現在開啟你熟悉的c++,跟隨作者的的思路,重走發現嫌犯的過程。

題目是建立專門的陣列類處理有關陣列的操作,要完成支援陣列操作的類的設計,增強c++內建陣列型別功能。——見:第14周-任務1-陣列類的構造

有同學向我求助,他的程式如下:

#include using namespace std;

class myarray

;myarray::myarray(int sz)

}myarray::myarray(int a,int sz) //由乙個內建型別的陣列初始化

}myarray::myarray(const myarray &a) //拷貝建構函式

}myarray::~myarray(void) //析構函式,注意釋放空間

myarray& myarray::operator =(const myarray &a) //過載「=」使得陣列物件可以整體賦值

int* destptr=arr;

int* srcptr=a.arr;

while(n--)

return *this;

}int& myarray::operator(int i) //過載,使得array物件也可以如c++普通陣列一樣,用a[i]形式取出值【選做】

bool myarray::operator == (myarray& a) //過載==,使得array物件能整體判斷兩個陣列是否相等(size相等且對應元素相等)

else }

return m;

}myarray myarray::operator + (myarray& a)

{ int n=a.size; //取a陣列的大小

if (size!=n) //大小不一致不能相加

游標在第二行一閃一閃,就是不見下文。

此症狀一般是陷入了死迴圈。經閱讀程式,已經輸出的多個0是160行cout

認真地讀一下這兩個過載函式,比較明顯的是第115行的a[i]=arr[i]+a[i];有些彆扭。a和a是myarray類的物件,而arr是當前物件的乙個成員(我想起一條胳膊和乙個人要加起來,哪能這樣!)修改為a.arr[i]=arr[i]+a.arr[i];(相當於a.arr[i]=this->arr[i]+a.arr[i];這就是胳膊和胳膊加了)。這樣,對加法結果正確有了把握。

再次執行,問題依舊。也看不出明顯的線索。請來法寶,祭起查詢bug的照妖鏡——除錯工具來幫忙。

在161行上設定斷點執行程式,用f11逐語句執行,進入myarray::operator +() 函式,即對加法的過載直至結束,未見異常。作為返回值的臨時物件a,其中的結果正確。a 的兩個屬性 size 及 arr 和 arr 為起始位址指向的值,也恰好是該求得值的結果。可以在117行也設定乙個斷點,觀察直至此時 相加結果 a 的值。下面是執行到此處時,從區域性變數視窗看到的結果(如果要看a.arr[1]及之後的值,可以用監視視窗):

單步跟蹤到myarray::operator =()函式,即對賦值的過載。很意外地,函式進入到了第59行的 if 語句中。目前程式的執行,所用到的陣列,其 size 均為10,應該這個 if 分支是執行不到的。而此時,區域性變數的值卻讓人大吃一驚:myarray::operator =()中形式引數 a  的 size 成員的值是乙個負數!見下圖:

(1)問題出在執行arr3=arr1+arr2;上;

(2)計算arr1+arr2,寫成函式呼叫形式是arr1.operator+(arr2),函式呼叫時,返回的結果是正確的;

(3)接著計算賦值,myarray::operator =(const myarray &a) 的形式引數 a 物件,將獲得 arr1+arr2 的結果,即實參是  arr1+arr2 的結果,更直觀地,執行的是 arr3.operator=(arr1+arr2); ,計算結果本來是正確的,但實參傳值給形參後,物件的 size 成員出錯了。

在實參給形參傳值時,採用的是複製的辦法,對類(物件)而言,需要有乙個複製建構函式支撐(這個學過)。複製建構函式可以是預設的。但是,如果類中有指標型別的成員時,必須自定義複製建構函式,從而能夠處理指標所指向空間的分配和**問題。

所以,嫌疑犯基本鎖定:myarray類的複製建構函式(也稱拷貝建構函式)。看41行開始的拷貝建構函式myarray::myarray(const myarray &a) 的定義,為this->arr成員分配了空間,並將形參物件中指向的資料一一進行複製,惟獨沒有做的,是為 this->size 賦值!我們需要在這個函式中,增加一行**:size = a.size;。

至此,案情大白於天下,錯誤得以糾正,程式得以正確執行。

課程支撐:我的 c++程式設計課程教學材料

官場 現形記

六年中學之軼事,若繁星點點 然歷經官場之事若皓月當空。某獨感之頗深,今特呈獻。初中三年中有兩年,我都是 黔首 然而某官癮頗大,從不中規中矩,經常 罵官 罵來罵去,卻讓別人看出了心病 其實我怎麼就不是個官呢?雖然 司馬昭之心,路人皆知 但我卻一直沒有這種契機 考場上,屢試不中。幾番周折後,才落個 名落...

Bug現形記(一) 乙個多重繼承程式的查錯

課程支撐 我的 c 程式設計課程教學材料 要完成的任務詳見第12周 任務2 雙肩挑幹部。題目要求 分別定義teacher 教師 類和cadre 幹部 類,採用多重繼承方式由這兩個類派生出新類teacher cadre 教師兼幹部 要求 1 在兩個基類中都包含姓名 年齡 性別 位址 等資料成員。2 在...

bug 記最近出現的非功能bug

1 android 4.1.2 的相容bug 一直以為android 測試 4 5 6就可以了,結果發現android4.1.2 和android4.3之間還是有差距的。處理辦法 驗證版本相容的時候,需要覆蓋所有系統版本 2 https和http 測試h5活動時,沒有考慮到能否支援https,上線後...