2016-11-08 40 views
-4

我正在用C++構造一個Polynomial類。目前,我正在讀入輸入並創建一個具有度數和係數(雙精度)數組的多項式對象。SegFault類中的析構函數[已更新]

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 
} 

我在我的main()的實現看起來是這樣的:

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

你需要一個賦值操作符和拷貝構造函數,但就是爲什麼'coefficients'應該首先被動態分配無明顯原因。 – EJP

+2

'P1->係數[idx] =係數;'可能是越界訪問。 –

+3

您的第一步是瞭解內存泄漏和段錯誤之間的區別。 –

回答

1

由於您未遵循Rule of Three,您的代碼崩潰。

您的push_back()調用會創建輸入對象的副本,但您的類缺少顯式的複製構造函數。編譯器提供了默認的一個,但它只是將指針從一個對象複製到另一個對象,所以最終會有多個對象試圖釋放相同的數組和崩潰。

您需要一個自定義副本構造函數,以便對coefficients數組進行深層複製。嘗試一些更喜歡這個:

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; 

話雖這麼說,在coefficients陣列將使用std::vector而不是更好實現。讓編譯器和STL做所有的繁重的工作適合你,比如:

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

保持我當前實現的數組[]係數我實現了一個複製構造函數和賦值運算符,如下所示:\t'degree = P.degree; \t係數= new double [degree + 1]; \t for(int i = 0; i <= degree; i ++) \t \t coefficients [i] = P.coefficients [i];'這是行不通的,我該如何修改這個工作? – user88453

+1

@ user88453請編輯您的問題以顯示您的最新代碼,請勿將其置於評論中。 –

+0

更新了我的代碼 – user88453