我正在做我的功課。目標是實現大操作類(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;
}
你的副本構造函數和析構函數是什麼樣的? – NathanOliver
您需要修剪和分隔文本。 –
@NathanOliver施工/銷燬部分(你需要向下滾動)。我試圖在評論中複製/粘貼代碼,但即使使用格式化也很糟糕。 – sanjam