巨大的错误。调试断言失败

时间:2015-06-10 11:57:51

标签: c++

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

一切都很好。但控制台显示&#34; -17891602-17891602-17891602&#34;然后出现错误&#34; Debug Assertation失败! ....表达式:_BLOCK_TYPE_IS_VALID(pHead-&gt; nBlockUse)&#34;。

问题出在&#34; return temp&#34;当我们重新定义operator +()时。这有什么问题?

1 个答案:

答案 0 :(得分:3)

此代码中存在相当多的错误

您的主要问题是您按值返回一个类(在operator+的末尾)没有为它定义一个复制构造函数。您应该阅读 3的规则(或其新的咒语 5的规则或甚至规则0 )。

基本上,由于您没有进行深层复制(为您提供的默认复制构造函数,因为您没有定义一个复制构造函数是浅复制品),原始temp和它的副本你实际上将两个点都归结为相同的buffer。当temp的析构函数在函数末尾运行时(假设没有发生NRVO),即使您返回的副本仍然指向它,它也会删除所述缓冲区。

您可以通过添加正确的复制构造函数来解决此问题(因此符合规则3)或更好的解决方法是使用std::vector<int>而不是手动管理的缓冲区所以不需要复制构造函数或析构函数( Zero of Zero )。

只需查看代码,就会出现更多问题。在你的添加函数中,你摆弄size实例的temp成员而不实际更改缓冲区。如果您碰巧将size设置为大于分配的缓冲区,那么您将注销触发 undefined behavoir 的有效内存的结尾。

Rule of 3/5/0

的有用链接