析构函数删除内存过早

时间:2015-11-14 20:39:24

标签: c++ memory memory-management destructor bigint

我对C ++中的内存管理很陌生。我创建了一个BigInt类,除了影响程序性能的析构函数之外,它现在已经完全实现了。但是,当我尝试实现析构函数时,我的程序崩溃了。

在下面的BigInts倍增代码中:

BigInt& BigInt::operator*=(BigInt const& other) {

    //copy of this and other
    BigInt* tempThis = new BigInt(*this); //1st number
    BigInt* tempOther = new BigInt(other); //2nd number

    //create temps so we can use value of BigInt before it is changed
    BigInt* sum = new BigInt(0); //holds the eventual answer

    BigInt* i = new BigInt(0);

    //add *this BigInt to sum otherTemp amount of times
    //this will yield multiplication answer.
    for (*i; *i < *tempOther; *i = *i + 1) {
        *sum += *this;
    }

    *this = *sum;

    return *this;

}

在for循环中调用* i = * i + 1时调用析构函数然后我认为它在我的析构函数中被删除,如下所示:

// destructor
BigInt::~BigInt() {
    delete[] this->bigIntVector;
}

// copy constructor
BigInt::BigInt(BigInt const& orig)
    : isPositive(orig.isPositive)
    , base(orig.base)
{
    this->bigIntVector = new BigIntVector(*(orig.bigIntVector));
}

一旦'i'被删除,一切都行不通,整个程序就会中断。

如果有人可以给我一些关于析构函数以及如何解决问题的指示,那将会很有帮助。感谢。

1 个答案:

答案 0 :(得分:1)

在C ++中,同样(可怕)的算法可以实现如下。

BigInt& BigInt::operator*=(BigInt const& other)
{
  if(other==0)
    return other;
  if(other> 1)
    for(BigInt old=*this,i=1; i!=other; ++i)
      operator+=old;
  else if(other<0) {
    BigInt old=*this;
    *this=0;
    for(BigInt i=0; i!=other; --i)
      operator-=old;
  }
  return*this;
}

假设来自int的构造函数,复制构造函数,增量operator++和加法operator+=都已正确实现(以及析构函数)。

不幸的是,您没有向我们提供更多信息,但您的复制构造函数和析构函数肯定已经破解:

this->bigIntVector = new BigIntVector(*(orig.bigIntVector));

之后是

delete[] this->bigIntVector;

为您提供未定义的行为(使用new进行分配,但使用delete[] - delete[]取消分配是针对使用new[]分配的内存。我怀疑你打算从复制构造函数中复制原始内存。但是,你没有。如果

class BigInt {
  size_t    size=0;                // number of some_types allocated
  some_type*bigIntVector=nullptr;  // ptr to memory allocated, if any
  /* rest of class */
};

然后可以实现复制构造函数(假设size是非静态的)

BigInt::BigInt(BigInt const&orig)
: size(orig.size()                                   // copy size
, bigIntVector(size? new some_type[size] : nullptr)  // allocate memory
{ std::memcpy(orig.bigIntVector, bigIntVector); }    // copy memory

然而,(差不多)使用

可以更容易地实现相同的功能
class BigInt
{
  std::vector<some_type> bigIntVector;
public:
  BigInt(BigInt const&) = default;
  BigInt(BigInt &&) = default;
  BigInt&operator=(BigInt const&) = default;
  BigInt&operator=(BigInt &&) = default;
  / * rest of class */
};

当为您自动正确创建复制和移动构造函数(以及相应的赋值运算符)时。您只需要解决默认构造函数,例如

BigInt::BigInt()                    // default constructor
: bigIntVector(1,some_type(0)) {}   // size=1, value=0

和内置整数类型的构造函数。如果您不熟悉C ++,请避免使用newdelete来支持标准库容器。