2016-11-08 8 views
-4

私はC++で多項式クラスを構築しています。現在、私は入力を読み込み、次数と係数(倍精度)配列を持つ多項式オブジェクトを作成しています。SegFault in class destructor [UPDATED]

Ex。

6x^3+7.4x^2-3.0x+9 
Polynomial 
---------- 
    degree = 3 
    coefficients[0] = 6 
    coefficients[1] = 7.4 
    coefficients[2] = 3.0 
    coefficients[3] = 9 

クラスのインスタンスを削除するときにエラーが発生します。私はこの問題はまさに... SEGFAULT私のエラーと一緒のように見えているのかわからないよ。助けてください

Segmentation fault: 11 

0x00007ffff71fdfbd in malloc_printerr (ptr=<optimized out>, 
    str=0x7ffff7304ad8 "free(): invalid next size (fast)", action=<optimized out>) at malloc.c:4983 
_int_free (have_lock=0, p=<optimized out>, av=<optimized out>) at malloc.c:3850 
__GI___libc_free (mem=<optimized out>) at malloc.c:2960 

、ありがとう!

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

/* Constructor for Polynomial */ 
Polynomial::Polynomial() 
{ 
    degree = 0; 
    coefficients = new double [1]; 
    coefficients[0] = 0; 
} 

Polynomial::Polynomial (const Polynomial & P) 
{ 
    *this = P; 
} 

代入演算子:

Polynomial & Polynomial::operator = (const Polynomial & P) 
{ 
    if (this != &P){ 
     degree = P.degree; 
     coefficients = new double [P.degree + 1]; 
     for (int i = 0; i <= P.degree; i++) 
      coefficients[i] = P.coefficients[i]; 
    } 
    return *this; 
} 

私のデストラクタは次のようになります。

/* Destructor for Polynomial */ 
Polynomial::~Polynomial() 
{ 
    delete [] coefficients; <--ERROR HERE 
} 

)(私のメインの内側に私の実装は次のようになります。

vector<Polynomial> Polys; 
Polynomial *P1 = new Polynomial(); 
... 
P1->degree = degreeInt; 
P1->coefficients[idx] = coefficient; 
Polys.push_back(*P1); 
delete P1; <-- ERROR HERE 
// Pushed Polynomial to Vector, create a new Polynomial object 
P1 = new Polynomial(); 
+2

代入演算子とコピーコンストラクタが必要ですが、なぜ係数が最初に動的に割り当てられるべきかはっきりした理由はありません。 – EJP

+2

'P1-> coefficients [idx] =係数;'はおそらく境界外アクセスです。 –

+3

あなたの最初のステップは、メモリリークとセグメンテーションの違いを知ることです。 –

答えて

1

Rule of Threeに従っていないため、コードがクラッシュします。

あなたのpush_back()コールは入力オブジェクトのコピーを作成しますが、クラスには明示的なコピーコンストラクタがありません。コンパイラはデフォルトのものを提供しますが、ポインタをあるオブジェクトから別のオブジェクトにコピーするだけで、同じ配列を解放してクラッシュする複数のオブジェクトになります。

coefficients配列のディープコピーを作成するカスタムコピーコンストラクタが必要です。言われて、coefficients配列は、より良い代わりにstd::vectorを使用して実装されること

class Polynomial 
{ 
private: 
    std::size_t degree; 
    double *coefficients; 

public: 
    Polynomial(std::size_t aDegree = 0); 
    Polynomial(const Polynomial &src); 
    ~Polynomial(); 

    Polynomial& operator=(const Polynomial &src); 

    void setDegree(std::size_t value); 
    void setCoefficient(std::size_t idx, double value); 
}; 

Polynomial::Polynomial(std::size_t aDegree) 
    : degree(aDegree), coefficients(0) 
{ 
    if (degree == std::numeric_limits<std::size_t>::max()) 
     throw std::domain_error("invalid degree value"); 

    coefficients = new double[degree + 1]; 
    std::fill(coefficients, coefficients + (degree + 1), double(0)); 
} 

Polynomial::Polynomial(const Polynomial &src) 
    : degree(src.degree), coefficients(0) 
{ 
    coefficients = new double[degree + 1]; 
    std::copy(src.coefficients, src.coefficients + (degree + 1), coefficients); 
} 

Polynomial::~Polynomial() 
{ 
    delete[] coefficients; 
} 

Polynomial& Polynomial::operator=(const Polynomial &src) 
{ 
    if (&src != this) 
    { 
     Polynomial tmp(src); 
     std::swap(degree, tmp.degree); 
     std::swap(coefficients, tmp.coefficients); 
    } 
    return *this; 
} 

void Polynomial::setDegree(std::size_t value) 
{ 
    if (degree != value) 
    { 
     if (value == std::numeric_limits<std::size_t>::max()) 
      throw std::domain_error("invalid degree value"); 

     double *new_coefficients = new double[value + 1]; 

     std::copy(coefficients, coefficients + (std::min(degree, value) + 1), new_coefficients); 
     if (value > degree) 
      std::fill(new_coefficients + (degree + 1), new_coefficients + (value + 1), double(0)); 

     delete[] coefficients; 
     coefficients = new_coefficients; 
     degree = value; 

     /* 
     alternatively: 

     Polynomial tmp(value); 
     std::copy(coefficients, coefficients + (std::min(degree, value) + 1), tmp.coefficients); 
     std::swap(degree, tmp.degree); 
     std::swap(coefficients, tmp.coefficients); 
     */ 
    } 
} 

void Polynomial::setCoefficient(std::size_t idx, double value) 
{ 
    if (idx > degree) 
     throw std::out_of_range("invalid index"); 
    coefficients[idx] = value; 
} 

std::vector<Polynomial> Polys; 
Polynomial *P1 = new Polynomial(degreeInt); 
P1->setCoefficient(idx, coefficient); 
Polys.push_back(*P1); 
delete P1; 

:より多くの代わりにこのような何かを試してみてください。

class Polynomial 
{ 
private: 
    std::size_t degree; 
    std::vector<double> coefficients; 

public: 
    Polynomial(std::size_t aDegree = 0); 

    void setDegree(std::size_t value); 
    void setCoefficient(std::size_t idx, double value); 
}; 

Polynomial::Polynomial(std::size_t aDegree) 
    : degree(aDegree) 
{ 
    if (degree == std::numeric_limits<std::size_t>::max()) 
     throw std::domain_error("invalid degree value"); 
    coefficients.resize(degree + 1, double(0)); 
} 

void Polynomial::setDegree(std::size_t value) 
{ 
    if (degree != value) 
    { 
     if (value == std::numeric_limits<std::size_t>::max()) 
      throw std::domain_error("invalid degree value"); 
     coefficients.resize(value + 1, double(0)); 
     degree = value; 
    } 
} 

void Polynomial::setCoefficient(std::size_t idx, double value) 
{ 
    coefficients[idx] = value; 
} 
+0

現在のarray []係数の実装を維持しました。コピーコンストラクタと代入演算子を実装しました。\t 'degree = P degrees; \t係数=新しい倍精度[度+1];\t for(int i = 0; i <= degree; i ++) \t \t係数[i] = P.coefficients [i]; 'これは機能しません。 – user88453

+1

@ user88453質問を編集して最新のコードを表示し、コメントには入れないでください。 –

+0

私のコードを更新しました – user88453