我正在用C ++构建一个Polynomial类。目前我正在读取输入并创建具有度和系数(双)数组的多项式对象。
实施例。
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();
答案 0 :(得分:1)
您的代码崩溃是因为您没有关注Rule of Three。
您的push_back()
调用会复制输入对象,但您的类缺少显式复制构造函数。编译器提供了一个默认值,但它只是将coefficients
指针从一个对象复制到另一个对象,因此最终会有多个对象尝试释放相同的数组并崩溃。
您需要一个自定义复制构造函数,它可以生成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;
}