2016-11-08 34 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