0

こんにちは、クラス内の動的メモリを削除しようとしていますが、次のエラーが発生します。

a.out(2830) malloc: *** error for object 0x7fb38a4039c0: pointer being freed was not allocated

* malloc_error_breakにブレークポイントを設定して、トラップの中止をデバッグします:6

これは、オーバーロードされた「=」演算子がクラスに直接アクセスしない「&」と関係があると思います。

class Polynomial{
    public:
        //Constructors / Destructors
        Polynomial();
        Polynomial(int tempNum, int * tempPoly);
        ~Polynomial();

        //Member Functions & Operator overloading
        //Addition
        Polynomial operator+(Polynomial& Poly);
        //Subtraction
        Polynomial operator-(Polynomial& Poly);
        //Multiplication
        Polynomial operator*(Polynomial& Poly);
        //Assignment
        Polynomial operator=(Polynomial Poly);

        //Insertion
        friend ostream& operator<<(ostream& os, Polynomial& Poly);
        //Extraction
        friend istream& operator>>(istream& is, Polynomial& Poly);

    private:
        //Data Members
        //Int array (degree of polynomial + 1)
        int * poly;
        int polyNum;
};


Implementation: 

Polynomial::Polynomial(){
    polyNum = 0;
}

Polynomial::~Polynomial(){
    //Delete Dynamic Memory
    delete [] poly;
}

Polynomial::Polynomial(int tempNum, int *tempPoly){

    poly = new int[tempNum+1];

    polyNum = tempNum;

    for (int i=0; i < tempNum; i++) {
        poly[i] = tempPoly[i];
    }
}

//Addition
Polynomial Polynomial::operator+(Polynomial &Poly){
    Polynomial temp;

    if(polyNum > Poly.polyNum){
        temp.polyNum = polyNum;
    }
    else{
        temp.polyNum = Poly.polyNum;
    }

    temp.poly = new int[temp.polyNum + 1];

    for(int i=0; i < temp.polyNum; i++){
        temp.poly[i] = Poly.poly[i] + poly[i];
    }

    return (temp);
}

//Subtraction
Polynomial Polynomial::operator-(Polynomial& Poly){
    Polynomial temp;

    if(polyNum > Poly.polyNum){
        temp.polyNum = polyNum;
    }
    else{
        temp.polyNum = Poly.polyNum;
    }

    temp.poly = new int[temp.polyNum + 1];

    for(int i=0; i < temp.polyNum; i++){
        temp.poly[i] = poly[i] - Poly.poly[i];
    }

    return (temp);
}

//Multiplication
Polynomial Polynomial::operator*(Polynomial& Poly){

    Polynomial temp;

    //make coefficient array
    temp.polyNum = (polyNum + Poly.polyNum) - 1;

    temp.poly = new int [temp.polyNum];

    for (int i = 0; i < temp.polyNum; i++)
    {
        for (int j = 0; j < Poly.polyNum; j++){
            temp.poly[i+j] += poly[i] * Poly.poly[j];
        }
    }

    return temp;
}

//Assignment
Polynomial Polynomial::operator=(Polynomial Poly){

    polyNum = Poly.polyNum;

    poly = new int[polyNum+1];

    for (int i=0; i < polyNum; i++) {
        poly[i] = Poly.poly[i];
    }

    return *this;
}

//Insertion
ostream& operator<<(ostream& os, Polynomial& Poly){

    for (int i=0; i < Poly.polyNum; i++) {
        os << Poly.poly[i] << " x^" << i;

        if(i != Poly.polyNum - 1){
            os << " + ";
        }
    }

    return os;
}

//Extraction
istream& operator>>(istream& is, Polynomial& Poly){

    int numP = 0;
    int * tempP;

    is >> numP;

    tempP = new int [numP+1];

    for (int i=0; i < numP; i++) {
        is >> tempP[i];
    }

    Poly.polyNum = numP;

    Poly.poly = new int[Poly.polyNum +1];

    for (int i=0; i < Poly.polyNum; i++) {
        Poly.poly[i] = tempP[i];
    }

    delete [] tempP;

    return is;
}

主要

int main(){

// Input Polynomial #1 (P1)
cout << "Input polynominal p1: " << endl;
Polynomial P1;
cin >> P1;

// Output Polynominal
cout << "p1(x) = " << P1 << '\n' << endl;

// Input Polynomial #2 (P2)
cout << "Input polynominal p2: " << endl;
Polynomial P2;
cin >> P2;

// Output Polynominal
cout << "p2(x) = " << P2 << '\n' << endl;

// Copy P2 to P3 and output P3
Polynomial P3;
P3 = P2;
cout << "Copy p2 to p3, p3(x) = " << P3 << '\n' << endl;

// Add P1 to P2 and output to P3
Polynomial P4;
P4 = P1 + P2;
cout << "p3(x) = p1(x) + p2(x) = " << P4 << '\n' << endl;

// Subtract P1 from P2 and output to P3
Polynomial P5;
P5 = P1 - P2;
cout << "p3(x) = p1(x) - p2(x) = " << P5 << '\n' << endl;

// Subtract P2 from P1 and output to P3
Polynomial P6;
P6 = P2 - P1;
cout << "p3(x) = p2(x) - p1(x) = " << P6 << '\n' << endl;

// Multiply P1 by P2 and output to P3
Polynomial P7;
P7 = P1 * P2;
cout << "p3(x) = p1(x) * p2(x) = " << P7 << '\n' << endl;

return 0;

}

4

2 に答える 2

4

デフォルトのコンストラクター(バグがあります)と代入演算子がありますが、コピーコンストラクターも定義する必要があります。そうしないと、aの各コピーは、コピー元のPolynomialポインターと同じポインターを取得し、polyそれらのコピーの1つが破棄されるたびに同じポインターの割り当てを解除します。2回目にこれが発生すると、すでにeddelete[]されているポインターを呼び出すため、このエラーが発生します。delete[]

コピーコンストラクタは次のようになります

Polynomial::Polynomial(const Polynomial& rhs) : poly(new int[rhs.polynum]), polynum(rhs.polynum) {
    std::copy(rhs.poly, rhs.poly + polynum, poly);
}

とは言うものの、使用するstd::vector場合は、代入演算子やコピーコンストラクターは必要なく、所有している数を追跡するための個別の変数もpoly必要ないので、そうすることをお勧めします。

また、デフォルトのコンストラクターを修正する必要があります。少なくとも、デストラクタに初期化されていないポインタがないように設定polyしてください。nullptrdelete[]

于 2012-09-27T14:55:10.847 に答える
4
Polynomial::Polynomial(){
    polyNum = 0;
}
Polynomial::~Polynomial(){
    //Delete Dynamic Memory
    delete [] poly;           // <-- bug
}

ここにバグがあります。polyはデフォルトのctorで初期化されていませんが、dtorで削除されています。

編集

本当にあなたは使用する必要がありますstd::vector<int>

class polynomial
{
  std::vector<int> _pol;       
public:
  size_t degree() const { return _pol.empty()? 0 : _pol.size() - 1; }
  polynomial() = default;                   // could be omitted (compiler generated anyway)
  polynomial(polynomial const&) = default;  // ----
  /// evaluate polynomial
  template<typename T>
  T operator() (T const&x) const
  {
    T y(0);
    T p(1);
    for(auto i : _pol) {
      y += *i * p;
      p *= x;
    }
    return y;
  }
  polynomial& operator+=(polynomial const&other)
  {
    auto j = other._pol.begin();
    for(auto i = _pol.begin(); i!=_pol.end() && j!=other._pol.end(); ++i,++j)
      *i += *j;
    for(; j != other._pol.end(); ++j)
      _pol.push_back(*j);
    return*this;
  }
  polynomial operator+(polynomial const&other) const
  {
    polynomial _p(*this);
    return _p += other;           
  }
  // etc
};

また、move ctorとoperatorを適切に実装してpolynomial sum = a+b;、一時的なコピー時にメモリの再割り当てが不要なような式を作成する必要があります。

于 2012-09-27T14:57:24.210 に答える