类析构函数中的SegFault [UPDATED] [英] SegFault in class destructor [UPDATED]
问题描述
我在C ++中构造一个多项式类。目前我正在读取输入并创建一个具有度和系数(双)数组的多项式对象。
6x ^ 3 + 7.4x ^ 2-3.0x + 9
多项式
------
degree = 3
系数[0] = 6
系数[1] = 7.4
系数[2] = 3.0
系数[3 ] = 9
我在删除我的类的实例时收到错误。我不知道什么问题是正确的...与 SEGFAULT
我的错误看起来像:
分段错误:11
0x00007ffff71fdfbd in malloc_printerr(ptr =< optimized out>,
str = 0x7ffff7304ad8free 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
谢谢!
我的构造函数如下:
/ *构造函数多项式* /
多项式::多项式()
{
degree = 0;
coefficients = new double [1];
coefficients [0] = 0;
}
多项式::多项式(常数多项式& P)
{
* this = P;
}
作业操作员:
多项式&多项式::运算符=(常数多项式& 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;
}
我的析构函数如下:
$ b b
/ *多项式的析构函数* /
多项式::〜多项式()
{
delete []系数; < - ERROR HERE
}
我的main :
向量<多项式> Polys;
多项式* P1 =新多项式();
...
P1-> degree = degreeInt;
P1-> coefficients [idx] = coefficient;
Polys.push_back(* P1);
delete P1; < - ERROR HERE
//向多边形推送多项式,创建一个新的多项式对象
P1 = new多项式();
您的代码崩溃,因为您未遵循三项规则。
您的 push_back()
调用会创建输入对象的副本,但是您的类缺少一个显式副本构造函数。编译器提供了一个默认的,但它只是将系数
指针从一个对象复制到另一个对象,所以你最终有多个对象试图释放相同的数组和崩溃。 / p>
您需要一个自定义副本构造函数,用于生成系数
数组的深层副本。尝试更像这样:
类多项式
{
private:
std: :size_t degree;
double * coefficients;
public:
多项式(std :: size_t aDegree = 0);
多项式(const Polynomial& src);
〜Polynomial();
多项式& operator =(const Polynomial& src);
void setDegree(std :: size_t value);
void setCoefficient(std :: size_t idx,double value);
};
多项式::多项式(std :: size_t aDegree)
:度(aDegree),系数(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));
}
多项式::多项式(const多项式和src)
:度(src.degree),系数(0)
{
系数= new double [degree + 1];
std :: copy(src.coefficients,src.coefficients +(degree + 1),coefficients);
}
多项式:: =多项式()
{
delete []系数;
}
多项式&多项式::运算符=(常数多项式& src)
{
if(& src!= this)
{
多项式tmp
std :: swap(degree,tmp.degree);
std :: swap(coefficients,tmp.coefficients);
}
return * this;
}
void多项式:: 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(coefficient,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 = new_coefficients;
degree = value;
/ *
或者:
多项式tmp(值);
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(无效索引);
coefficients [idx] = value;
}
std :: vector< Polynomial> Polys;
多项式* P1 =新多项式(degreeInt);
P1-> setCoefficient(idx,coefficient);
Polys.push_back(* P1);
delete P1;
也就是说,系数
更好地实现使用 std :: vector
。让编译器和STL为你做所有繁重的工作,例如:
类多项式
{
private:
std :: size_t degree;
std :: vector< double>系数;
public:
多项式(std :: size_t aDegree = 0);
void setDegree(std :: size_t value);
void setCoefficient(std :: size_t idx,double value);
};
多项式::多项式(std :: size_t aDegree)
:degree(aDegree)
{
if(degree == std :: numeric_limits& size_t> :: max())
throw std :: domain_error(degree degree value);
coefficients.resize(degree + 1,double(0));
}
void多项式:: 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;
}
I am constructing a Polynomial class in C++. Currently I am reading in input and creating a Polynomial object with a degree and coefficient (double) array.
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
I am getting an error when I am deleting an instance of my class. I am not sure what the problem is exactly...along with a SEGFAULT
my error looks like:
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
Please help, thanks!
My constructors looks like:
/* Constructor for Polynomial */
Polynomial::Polynomial ()
{
degree = 0;
coefficients = new double [1];
coefficients[0] = 0;
}
Polynomial::Polynomial (const Polynomial & P)
{
*this = P;
}
Assignment Operator:
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;
}
My destructor looks like:
/* Destructor for Polynomial */
Polynomial::~Polynomial ()
{
delete [] coefficients; <--ERROR HERE
}
My implementation inside my main() looks like this:
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();
Your code crashes because you are not following the Rule of Three.
Your push_back()
call makes a copy of the input object, but your class is missing an explicit copy constructor. The compiler provides a default one, but it simply copies the coefficients
pointer from one object to another, so you end up with multiple objects trying to free the same array and crash.
You need a custom copy constructor that makes a deep copy of the coefficients
array. Try something more like this instead:
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;
That being said, the coefficients
array would be better implemented using a std::vector
instead. Let the compiler and STL do all the heavy work for you, eg:
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;
}
这篇关于类析构函数中的SegFault [UPDATED]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!