我正在创建一个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/

10-11 22:40
查看更多