class data corruption c ++

时间:2016-03-03 21:32:03

标签: c++ class

我正在编写一个应该加,减和乘多项式的程序。同样,重载=, - ,+, - =,+ =,*,* =运算符。我需要使用动态内存分配。 我能够让程序运行我可以从用户那里获得输入发送给方法来进行计算。我遇到的问题是使用Add函数返回值,输出多项式的开头已损坏。对我而言,它看起来像地址或垃圾。我试了几个小时才弄清楚出了什么问题;然而,我撞墙,我正在失去时间和生产力。我知道代码的数学方面并不好,但是现在我想确保我有一个正确的输入和输出。我非常感谢我能得到的任何指导或建议。

这是我的代码以及示例输出:

  

Polynomial.h

#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H

class Polynomial
{

private:
    //A dynamic array of coefficients
    int * m_coefficientArray;

    //Holds the degree of a polynomial
    int m_degree;

    //Helper function creates a costume size array to hold operation (+ , - etc) results
    Polynomial(int size);

public:

    //<<<<<<< Methods >>>>>>>//

    //Default Constructor
    Polynomial();

    //Costume Constructor
    Polynomial(int * coefficientArray, int degree);

    //Copy Constructor to preserve data from being mutated
    Polynomial(const Polynomial & copy);

    //Destructor returns memory to the OS after no longer needed
    ~Polynomial();

    //Assingment op overload
    Polynomial & operator = (const Polynomial & rhs);

    //Addition
    Polynomial Add(Polynomial & other);

    //subtraction
    Polynomial Subtract(Polynomial & other);

    //Gets input from the user
    void Get_Data();

    //Display data
    void Display_Poly();

    // + operator overload
    Polynomial operator + (Polynomial & other);

};
#endif
  

Polynomial.cpp

#include "Polynomial.h"
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

//Default Constructor
Polynomial::Polynomial()
{
    m_degree = 1;
    m_coefficientArray = new int[1];                            
    m_coefficientArray[0] = 0;  //First element of m_coefficientArray is 0.
}

//Costume Constructor
Polynomial::Polynomial(int * coefficientArray, int degree)                   
{
    m_degree = degree;

    m_coefficientArray = new int[degree];                       

    for (int i = 0; i < degree; i++)
    {
        m_coefficientArray[i] = coefficientArray[i];
    }
}

//Copy Constructor to preserve data from being mutated
Polynomial::Polynomial(const Polynomial & copy)
{
    m_degree = copy.m_degree;

    m_coefficientArray = new int[m_degree];          

    for (int i = 0; i < m_degree; i++)
    {
        m_coefficientArray[i] = copy.m_coefficientArray[i];
    }

}

//Destructor returns memory to the OS after no longer needed
Polynomial::~Polynomial()
{
    delete[] m_coefficientArray;
    m_degree = 0;
    m_coefficientArray = nullptr;
}

//Assignment operator overload
Polynomial &Polynomial::operator = (const Polynomial & rhs)
{
    if (this == &rhs)
    {
        return *this;
    }
    else
    {
        delete[] m_coefficientArray;

        m_coefficientArray = new int[rhs.m_degree];            

        m_degree = rhs.m_degree;

        for (int i = 0; i < m_degree; i++)
        {
            m_coefficientArray[i] = rhs.m_coefficientArray[i];
        }
    }
    return *this;
}

// Adds two polynomials together, then returns the sum
Polynomial Polynomial::Add(Polynomial & other)
{
    int size = (m_degree >= other.m_degree) ? m_degree : other.m_degree;

    Polynomial result(size);

        for (int i = 0; i < size; i++)
        {
            result.m_coefficientArray[i] = m_coefficientArray[i] + other.m_coefficientArray[i];
        }


        return result;
}

//Get users input
void Polynomial::Get_Data()
{



    cout << "Enter degree of polynomial: ";
    cin >> m_degree;    

    m_coefficientArray = new int[m_degree + 1]; //Array to hold the coeffs for polynomial     
    for (int i = m_degree; i >= 0; i--)
    {
        cout << "Enter coeffecient of x^" << i << ": ";
        cin >> m_coefficientArray[i];
    }
}

//Display and orginize program output
void Polynomial::Display_Poly()
{
    int i = 0;

    for (i = m_degree; i > 0; i--)
    {
        if (m_coefficientArray[i] == 0)
        {   //Prevents output like "0x^2, which is really just 0
            cout << "";
        }
        else if (i == 1)
        {   //Pevents output like "3x^1", the 1 is not necessary
            cout << m_coefficientArray[i] << "x" << " + ";
        }
        else if (m_coefficientArray[i] == 1)
        {   //Prevents output like "1x^2 + 1x", the 1 is not necessary
            cout << "x^" << i << " + ";
        }
        else //Normal, if others dont occur (coeff, variable, '^', power, '+')
        {
            cout << m_coefficientArray[i] << "x^" << i << " + ";
        }
    }
        cout << m_coefficientArray[i] << "\n";
}

//This constructor allows you to set the size of the array
Polynomial::Polynomial(int size)
{
    //check for invalid input
    if (size <= 0)
    {
        m_degree = 1;
    }//Make the default array of size 1 in this case
    else
    {
        m_degree = size;

        //Create an array of the given size
        m_coefficientArray = new int[m_degree + 1];


        //init everything to zero
        for (int i = 0; i <= m_degree; i++)
        {
            m_coefficientArray[i] = 0;
        }
    }


}

//Subtracts two polynomials, then returns the result
Polynomial Polynomial::Subtract(Polynomial & other)
{
    int size = (m_degree >= other.m_degree) ? m_degree : other.m_degree;
    Polynomial sub(size);

    for (int i = 0; i < size; i++)
    {
        sub.m_coefficientArray[i] = m_coefficientArray[i] - other.m_coefficientArray[i];
    }

    return sub;
}

// Addition operator overload
Polynomial Polynomial::operator + (Polynomial & other)
{

    return Add(other);
}
  

Main.cpp的

#include "Polynomial.h"
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

int main()
{
    Polynomial poly1;
    Polynomial poly2;
    Polynomial poly3;

    //input
    poly1.Get_Data();
    poly2.Get_Data();

    //output
    cout << "First Polynomial:" << endl;
    poly1.Display_Poly();

    cout << "Second Polynomial:" << endl;
    poly2.Display_Poly();

    cout << "Addition result " << endl;
    poly2.Add(poly1).Display_Poly();

    cout << "Subtraction Result " << endl;
    poly1.Subtract(poly2).Display_Poly();

    cout << "+ Operator Test " << endl;
    poly3 = poly1 + poly2;

    return 0;
}

节目输出:

  

输入多项式次数:1

     

输入x ^ 1:2

的系数      

输入x ^ 0:3

的系数      

输入多项式次数:2

     

输入x ^ 2:1

的系数      

输入x ^ 1:2

的系数      

输入x ^ 0:3

的系数      

First Polynomial:

     

2x + 3

     

第二多项式:

     

x ^ 2 + 2x + 3

     

添加结果

     

-33686019x ^ 2 + 4x + 6

     

减法结果

     

-33686019x ^ 2 + 0

     

操作员+测试

     

-33686019x ^ 2 + 4x + 6

     

按任意键继续。 。

3 个答案:

答案 0 :(得分:1)

您有两个重大错误。

错误1:

正如其他人提到的那样,如果您添加两个Polynomials,则会出现错误,而一个Polynomial与另一个Polynomial的程度不同:

错误2:

另一个错误是,在Polynomial(int)构造函数中,如果大小为0,则无法将m_coefficientArray设置为nullptr。因此,如果您要执行此操作:

{
   Polynomial p(0);
}

这一行会在销毁时导致未定义的行为,因为析构函数将尝试在未初始化的指针上调用delete。即使它是private,您应该确保所有构造函数都不会导致不必要的问题。

您的代码还有其他问题需要解决。一个是赋值运算符可以很容易地用这种方式编写:

Polynomial &Polynomial::operator = (const Polynomial & rhs)
{
    // make a temp copy of the passed-in object
    Polynomial temp(rhs);

    // swap out temp's internals with our internals 
    std::swap(temp.m_coefficientArray, m_coefficientArray);
    std::swap(temp.m_degree, m_degree);

    // return ourselves
    return *this;
}  // temp dies off with the old data here

这是copy / swap idiom。如果new[]抛出异常,则当前的赋值运算符实现将无法正常工作,因为您已经释放了内存。使用copy / swap,这种情况永远不会发生,因为如果在创建temp时出现问题,原始对象不会受到任何损害。

答案 1 :(得分:0)

Add Subtract时,您正在使用this->m_degree != other.m_degreethis->m_degree方法中没有的内存进行阅读。考虑2other.m_degree3this->m_coefficientArray[3]时的情况。您将尝试从QAbstractListModel读取,但这超出了您分配的数组范围。

答案 2 :(得分:0)

int size = (m_degree >= other.m_degree) ? m_degree : other.m_degree;

for (int i = 0; i < size; i++)
    ... m_coefficientArray[i] + other.m_coefficientArray[i]

您将size设置为两种尺寸中的最大值,但是您遍历两个阵列size次。如果数组的长度不相等,那么你就会超过其中一个数组的界限。

由于您需要迭代两个数组中的每个元素,因此最好分别对每个元素进行循环。

for i from 0 to size
    result[i] += arr[i]
for i from 0 to other.size
    result[i] += other.arr[i]

您也可以循环到任一数组的最小大小,然后迭代另一个数组的剩余部分。它可能会更快,但需要更多的写作。