我正在创建一个HugeInt类。我的主要:
#include <iostream>
#include <string>
int main(int argc, char* argv[])
{
HugeInt hi1("123");
HugeInt hi2("456");
std::cout << hi1 + hi2 << std::endl;
return 0;
}
和我的HugeInt类:
#include <iostream>
#include <string>
#define SIZE 32
class HugeInt
{
friend std::ostream & operator<<(std::ostream &, const HugeInt &);
public:
HugeInt();
HugeInt(const char *);
~HugeInt();
HugeInt operator+(const HugeInt &) const;
private:
int * buffer;
int size;
};
和他的方法:
HugeInt::HugeInt()
{
size = SIZE;
buffer = new int[size];
for (int i = 0; i < size; i++) {
buffer[i] = 0;
}
}
HugeInt::HugeInt(const char * hugeNumber)
{
size = strlen(hugeNumber);
buffer = new int[size];
for (int i = size - 1; i >= 0; i--) {
buffer[i] = hugeNumber[i] - '0';
}
}
HugeInt::~HugeInt()
{
delete[] buffer;
}
HugeInt HugeInt::operator+(const HugeInt & operand) const
{
HugeInt temp;
int carry = 0;
if (size >= operand.size)
temp.size = size;
else
temp.size = operand.size;
for (int i = 0; i < temp.size; i++) {
temp.buffer[i] = buffer[i] + operand.buffer[i] + carry;
if (temp.buffer[i] > 9) {
temp.buffer[i] %= 10;
carry = 1;
}
else {
carry = 0;
}
}
return temp;
}
std::ostream & operator<<(std::ostream & output, const HugeInt & complex)
{
for (int i = 0; i < complex.size; i++)
output << complex.buffer[i];
return output;
};
一切都编译良好。但是控制台显示“-17891602-17891602-17891602”,然后显示错误“调试声明失败!...。表达式:_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse)”。
当我们重新定义operator +()时,问题出在“返回温度”中。怎么了
最佳答案
此代码中有很多错误
您的主要问题是您要按值返回一个类(在operator+
的末尾),而没有为其定义副本构造函数。您应该阅读3规则(或其较新的咒语5规则,甚至0规则)。
基本上,由于您不进行深层复制(未定义时提供给您的默认复制构造函数会进行浅层复制),因此原始temp
和您的实际副本都将两者都指向了相同的buffer
。当temp
的析构函数在函数末尾运行时(假定未发生NRVO),即使您返回的副本仍指向该缓冲区,它也会删除该缓冲区。
您可以通过添加正确的副本构造函数(从而满足3的规则)来解决此问题,或者更好的解决方法是使用std::vector<int>
而不是手动管理的缓冲区,因此不需要副本构造函数或析构函数(零规则)。
只是查看您的代码,还有其他一些问题。在您的add函数中,您无需实际更改缓冲区就可以操纵size
实例的temp
成员。如果您碰巧将size
设置为大于分配的缓冲区,那么您将注销有效内存的末尾,从而触发未定义的行为。
Rule of 3/5/0的有用链接
关于c++ - HugeInt错误。调试断言失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30755656/