类析构函数中的SegFault [UPDATED] [英] SegFault in class destructor [UPDATED]

查看:186
本文介绍了类析构函数中的SegFault [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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆