2015-12-08 209 views
0

我正在做我的功課。目標是實現大操作類(BigInt)。調試斷言失敗C++

初始化:BigInt類的每個對象都被構造爲一個動態數組。數組的成員是由用戶輸入的字符串的數字(以相反順序 - 這對我來說更容易實現操作)。

類BigInt的規格: 兩個BigInts之間的關係(更小,更大,相等), 操作:加,減,乘。 關係,加法和減法運作良好。問題在於乘法。

問題:當我測試沒有乘法的程序時,它運行良好。當我取消註釋乘法時,在寫入關係的結果,加法和減法之後程序中斷。

錯誤:調試斷言失敗。當我進入調試模式下,我看到它還算不錯,直到行:

DELETE [] m; 

我看了關於調試斷言其他問題,並意識到我不能刪除BigInt類的對象與delete[] m,因爲我已經寫在我的析構函數中。我嘗試了DELETE m。當我這樣做,它打印出不錯的結果,但它的行後壞:

cout << "before returing m" << endl;. 

錯誤:請重新調試斷言失敗了,但他補充說這一次:

L buffer is too small.

當我進入調試模式,它讓我發現,斷點處於深度拷貝構造函數行:

strcpy_s(myDigits, myNumDigits, source.myDigits); 

現在我不知道該怎麼辦,因爲它與加法和減法效果很好(但我想,在這些操作深拷貝構造函數從未使用過)。

因此,我需要回答的問題是:哪裏是錯誤,是使用delete[]delete還是在執行深拷貝構造函數(或其他地方)?

我附上我的代碼。我不希望它很難審查,所以我只附加解決我的問題所需的部分(構造函數,析構函數,乘法的部分代碼)。如果您認爲我應該多加註意,請在評論中告訴我。

建設/破壞:

BigInt::BigInt(string digits) 
{ 
    const char* s = digits.c_str(); 
    int k; 
    int limit = 0; 
    myNumDigits = 0; 
    if (strlen(s) == 0) 
    { 
     mySign = positive; 
     //myDigits = new char[2]; 
     myDigits = nullptr; 
     myNumDigits = 0; 
     cout << "Empty string!" << endl; 
     return; 
    } 
    if (digits[0] == '-') 
    { 
     mySign = negative; 
     limit = 1; 
    } 
    else 
    { 
     mySign = positive; 
     if (digits[0] == '+') 
      limit = 1; 
    } 
    const char*help = digits.c_str(); 
    myDigits = new char[strlen(s) + 1 - limit]; 
    // reversed order 
    for (k = strlen(help) - 1; k >= limit; k--) 
    { 
     if (!isdigit(digits[k])) 
     { 
      cout << "onlu digits and sign! " << endl; 
      exit(1); 
     } 
     AddSigDigit(digits[k] - '0'); //incrementation 
    } 
    myDigits[strlen(s) - limit] = '\0'; 
} 

// Copy constructor -deep 
BigInt::BigInt(const BigInt& source) 
{ 
    // can do shallow copy of a number 
    myNumDigits = source.myNumDigits; 

    //deep copy of array 
    if (source.myDigits) 
    { 
     myDigits = new char[myNumDigits + 1]; 
     strcpy_s(myDigits, myNumDigits, source.myDigits); //BREAKPOINT!!!!! 
     myDigits[myNumDigits] = '\0'; 
    } 
    else 
     myDigits = 0; 
} 
// move copy constructor 
BigInt::BigInt(BigInt&&other) { 

    myNumDigits = other.myNumDigits; 
    myDigits = other.myDigits; 
    other.myNumDigits = 0; 
    other.myDigits = 0;//null pointer 
} 
BigInt::BigInt(Sign sign, int NumDig, char* sum) { 
    mySign = sign; 
    myNumDigits = NumDig; 
    myDigits = sum; 
    sum = 0; 
} 
BigInt::~BigInt() { 
    delete[] myDigits; 
} 

幫助功能:

int BigInt::GetDigit(int k) const 

{ 
    if (0 <= k && k < NumDigits()) 
    { 
     return myDigits[k] - '0'; 
    } 
    return 0; 
} 
void BigInt::AddSigDigit(int value) 
// adding value on place of most significant digit 
{ 
    myDigits[myNumDigits] = '0' + value; 
    myNumDigits++; 
} 

乘法:

BigInt BigInt::mul(const BigInt&num)const { 

char* a =new char[num.myNumDigits+1]; 
strcpy(a, num.myDigits); 
a[num.myNumDigits] = '\0'; 
cout << "a" << a << endl; 
char* b = new char[myNumDigits + 1]; 
strcpy(b,myDigits); 
b[myNumDigits] = '\0'; 
cout << "b" << b << endl; 
string temp; 
BigInt* m = new BigInt("0"); 
//cout << *m << endl; 
unsigned int i; 
for (i = 0; i < strlen(a); i++) { 
int carry = 0; 
temp = string (i, '0'); 
unsigned int j; 
for (j = 0; j < (int)strlen(b); j++) { 
    int pom; 
    pom = (a[i] - '0') * (b[j] - '0') + carry; 
    temp += ((char)(pom % 10 + '0')); 
    carry = pom/10; 
} 

if (carry != 0) 
    temp += (carry + '0'); 
cout <<"temp unreversed in i. iteration" <<temp<<" " <<i << endl; 
reverse(temp.begin(), temp.end()); 
cout << "temp reversed in i. iteration" << temp << " " << i << endl; 
BigInt* n = new BigInt((*m).add(BigInt(temp.substr(cut(temp))))); 
std::cout << "n in i. iteration " << *n<<"i."<<i<<endl; 
delete m; 
std::cout << " delete pass" << endl; 
m = n; 
n = nullptr; 
} 
cout << "before returing m" << endl; 
return (*m); //BECAUSE OF THIS LINE THERE IS BREAKPOINT IN COPY CONSTRUCTOR 
cout << "after returing m" << endl; 
} 

int BigInt::cut(const string& i)const { 
int index = 0; 
while (i[index] == '0' && index < i.size() - 1) index++; 
return index; 
} 
+0

你的副本構造函數和析構函數是什麼樣的? – NathanOliver

+0

您需要修剪和分隔文本。 –

+0

@NathanOliver施工/銷燬部分(你需要向下滾動)。我試圖在評論中複製/粘貼代碼,但即使使用格式化也很糟糕。 – sanjam

回答

1

mul代碼創建m一次,delete的IT的循環。歡迎來到UB。