ОБНАРУЖЕНА КОРРУПЦИЯ КАРТЫ: после нормального блока (# 195) при 0x00913A10. CRT обнаружил, что приложение записало в память после завершения буфера кучи - PullRequest
0 голосов
/ 14 января 2019

У меня есть следующий код на VS для написания класса полиномиального калькулятора. Файл .h как показано ниже

#pragma once
#include <stdio.h>
#include <iostream>
using namespace std; 

class Poly {
private:
    int coefficient=0;
    int largest_exponent=0;
    int* array = nullptr;
    //string input;
public:
    //constructor
    Poly(int coefficient, int largest_exponent);
    Poly(int coefficient); // assume the exponent or power is 0
    Poly(); // empty constructor 0 coeffecient and 0 exponent
    Poly(const Poly& poly); //copy constructor

    //destructoer
    ~Poly();
    int getCoeff(int num);
    void setCoeff(int coeff, int exp);
    //delete and valgrind

    //Overload

    Poly operator*(const Poly &poly) const;
    Poly operator+(const Poly &poly) const;
    //Poly operator+(const Poly &poly);
    Poly operator-(const Poly &poly) const;

    Poly operator*=(const Poly &poly) const;
    Poly operator+=(const Poly &poly) const;
    Poly operator-=(const Poly &poly) const;

    Poly operator=(const Poly &poly) const;
    Poly operator==(const Poly &poly) const;
    Poly operator!=(const Poly &poly) const;

    friend ostream& operator<<(ostream &os, const Poly &poly);
    friend istream& operator>>(istream &is, Poly &poly);
};

и мой .cpp файл как показано ниже

#include "pch.h"
#include "Poly.h"


Poly::Poly(int coefficient, int largest_exponent) { // largest component must be +ve value 
    this->largest_exponent = largest_exponent;
    this->coefficient = coefficient;

    this->array = new int[largest_exponent+1];
    for (int i = 0; i <= largest_exponent; i++) {
        this->array[i] = 0;    // Initialize all elements to zero.
    }
    this->array[largest_exponent] = coefficient;
}

Poly::Poly(int coefficient) { // assume the exponent or power is 0
    this->largest_exponent = 0;
    this->coefficient = coefficient;

    this->array = new int[1];
    for (int i = 0; i <= 0; i++) {
        this->array[i] = 0;    // Initialize all elements to zero.
    }
    this->array[0] = coefficient;
}

Poly::Poly() { // empty constructor 0 coeffecient and 0 exponent
    this->coefficient = 0;
    this->largest_exponent = 0;

    //this->array = new int[1];
    this->array = new int[2];
    for (int i = 0; i <= 0; i++) {
        this->array[i] = 0;    // Initialize all elements to zero.
    }   
}

Poly::Poly(const Poly& poly) { //copy constructor
    this->coefficient = poly.coefficient;
    this->largest_exponent = poly.largest_exponent;

    this->array = new int[poly.largest_exponent+1];
    for (int i = 0; i <= poly.largest_exponent; i++) {
        this->array[i] = poly.array[i];    // Initialize all elements to zero.
    }
}

Poly::~Poly() {
    cout << "deleting Polynomial array" << endl;
    delete[] array;
    array = nullptr; //or delete array;
}

int Poly::getCoeff(int num) {
    int coeff = this->array[num];
    if (coeff > -33686019) {
        cout << "coeff of power " << num << " of P is: " << coeff << endl;
        return this->array[num];
    }
    else {
        cout << "this Exponent does not exist in the polynomial" << endl;
        return 0;
    }
}

void Poly::setCoeff(int coeff, int exp) {
    int* newarray = new int[(abs(exp)) + 1];

    for (int i = 0; i <= (abs(exp));i++) {
        newarray[i] = 0;
    }

    for (int i = 0; i <= this->largest_exponent;i++) {
        newarray[i] = this->array[i];
    }
    newarray[(abs(exp))] = coeff;
    this->array = newarray;
    //this->array[abs(exp)] = coeff; 
    if ((abs(exp)) > this->largest_exponent) {
        this->largest_exponent = (abs(exp));
    }
}

ostream& operator<<(ostream &os, const Poly &poly) {
    bool flag = false;

    for (int i = poly.largest_exponent; i >= 0; i--) {
            if (poly.array[i] > 0 && i > 1) {
                os << " +" << poly.array[i] << "x^" << i;
                flag = true;
            }
            if (poly.array[i] < 0 && i > 1) {
                os << " " << poly.array[i] << "x^" << i;
                flag = true;
            }
            if (poly.array[i] > 0 && i == 1) {
                os << " +" << poly.array[i] << "x";
                flag = true;
            }
            if (poly.array[i] < 0 && i == 1) {
                os << " " << poly.array[i] << "x";
                flag = true;
            }
            if (poly.array[i] > 0 && i == 0) {
                os << " +" << poly.array[i];
                flag = true;
            }
            if (poly.array[i] < 0 && i == 0) {
                os << " " << poly.array[i];
                flag = true;
            }
    }
    if (flag == false) {
        os << " 0";
    }
    return os;
}

istream& operator>>(istream &is, Poly &poly) {  
    poly.largest_exponent = 0;  
    int * temparray=new int[0]; 
    int coeff;
    int exp;
    cout << "Enter terms for polynomial A.  Enter a coefficient " << endl;
    if (std::cin >> coeff >> exp) {
        if (coeff != -1 && exp != -1) {
            poly.array[exp] = coeff;
            if (poly.largest_exponent < coeff)
                poly.largest_exponent = coeff;
        }

    }
    return is;
}

Poly Poly::operator*(const Poly &poly) const {
    Poly * temp = new Poly();
    temp->largest_exponent = poly.largest_exponent + this->largest_exponent;

    for (int k = 0; k <= temp->largest_exponent; k++) {
        temp->array[k] = 0;    // Initialize all elements to zero.
    }

    for (int i = 0; i <= this->largest_exponent; i++) {
        for (int j = 0; j <= poly.largest_exponent; j++) {
            temp->array[i + j] += (this->array[i] * poly.array[j]);
        }
    }
    return *temp;
}

Poly Poly::operator+(const Poly &poly) const {
    Poly * temp = new Poly();
    int smallest_exponent;
    if (this->largest_exponent >= poly.largest_exponent) {
        temp->largest_exponent = this->largest_exponent;
        smallest_exponent = poly.largest_exponent;
        for (int i = 0; i <= temp->largest_exponent; i++) {
            temp->array[i] = this->array[i];
        }
    }
    else {
        temp->largest_exponent = poly.largest_exponent;
        smallest_exponent = this->largest_exponent;
        for (int i = 0; i <= temp->largest_exponent; i++) {
            temp->array[i] = poly.array[i];
        }
    }

    for (int i = 0; i <= smallest_exponent; i++) {

        temp->array[i] = poly.array[i] + this->array[i];
    }
    return *temp;
}

Poly Poly::operator-(const Poly &poly) const {
    Poly * temp = new Poly();
    int smallest_exponent;

    if (this->largest_exponent >= poly.largest_exponent) {
        temp->largest_exponent = this->largest_exponent;
        smallest_exponent = poly.largest_exponent;
        for (int i = 0; i <= temp->largest_exponent; i++) {
            temp->array[i] = this->array[i];
        }
    }
    else {
        temp->largest_exponent = poly.largest_exponent;
        smallest_exponent = this->largest_exponent;
        for (int i = 0; i <= temp->largest_exponent; i++) {
            temp->array[i] = poly.array[i];
        }
    }

    for (int i = 0; i <= smallest_exponent; i++) {
        temp->array[i] = this->array[i] - poly.array[i];
    }

    if (this->largest_exponent < poly.largest_exponent) {
        for (int i = smallest_exponent+1; i <= poly.largest_exponent; i++) {
            temp->array[i] = temp->array[i]*-1;
        }
    }
    return *temp;   
}

а это мой драйвер .cpp

#include "pch.h"
#include <iostream>
#include "Poly.h"

int main()
{
    Poly A(-5,1);
    int x = A.getCoeff(1);
    A.setCoeff(7,3);
    A.setCoeff(6,2);
    Poly B(2);
    B.setCoeff(8,2);
    B.setCoeff(8,0);
    Poly C; 
    Poly D(A);
    cout << A << endl;
    cout << B << endl;
    cout << C << endl;
    cout << D << endl;
    Poly E = B + A;
    cout << E << endl;
    Poly F = A-B;
    cout << F << endl;
    Poly G = B-A;   
    cout << G << endl;
    Poly H = B * A;
    cout << H << endl;
    cout << endl;
    //Poly I;
    //cin >> I;
    //cout << I << endl;
    return 0;


}

Всякий раз, когда я пытаюсь запустить этот код, я получаю сообщение об ошибке ниже, даже когда я нажимаю продолжить, результаты кажутся хорошими. У кого-нибудь есть идея, где я испортил память?

Ошибка отладки!

Программа:

ОБНАРУЖЕНА КОРРУПЦИЯ КАРТЫ: после блока Normal (# 195) при 0x00A03A10. CRT обнаружил, что приложение записало в память после завершения буфера кучи.

(Нажмите «Повторить» для отладки приложения) Обнаружена критическая ошибка c0000374 Poly.exe вызвал точку останова.

Исключительная ситуация при 0x77DC61E4 (ntdll.dll) в Poly.exe: 0xC0000374: повреждена куча (параметры: 0x77DE2378). Необработанное исключение в 0x77DC61E4 (ntdll.dll) в Poly.exe: 0xC0000374: повреждена куча (параметры: 0x77DE2378).

'Poly.exe' (Win32): загружен 'C: \ WINDOWS \ SysWOW64 \ user32.dll'. Не удается найти или открыть файл PDB. «Poly.exe» (Win32): загружен «C: \ WINDOWS \ SysWOW64 \ gdi32.dll». Не удается найти или открыть файл PDB. «Poly.exe» (Win32): загружен «C: \ WINDOWS \ SysWOW64 \ imm32.dll». Не удается найти или открыть файл PDB. «Poly.exe» (Win32): загружен «C: \ WINDOWS \ SysWOW64 \ msctf.dll». Не удается найти или открыть файл PDB. «Poly.exe» (Win32): загружен «C: \ WINDOWS \ SysWOW64 \ uxtheme.dll». Не удается найти или открыть файл PDB. «Poly.exe» (Win32): загружен «C: \ WINDOWS \ SysWOW64 \ combase.dll». Не удается найти или открыть файл PDB. «Poly.exe» (Win32): загружен «C: \ WINDOWS \ SysWOW64 \ dwmapi.dll». Не удается найти или открыть файл PDB. «Poly.exe» (Win32): загружен «C: \ WINDOWS \ SysWOW64 \ ole32.dll». Не удается найти или открыть файл PDB. «Poly.exe» (Win32): загружен «C: \ WINDOWS \ SysWOW64 \ kernel.appcore.dll». Не удается найти или открыть файл PDB. Исключительная ситуация: 0x77D21796 (ntdll.dll) в Poly.exe: 0xC0000005: расположение чтения нарушения доступа 0x00000000.

1 Ответ

0 голосов
/ 14 января 2019

Ваш код содержит довольно много ошибок.

Во-первых, не помечайте все операторы как const, если они не постоянны. Оператор присваивания никогда не бывает постоянным.

Во-вторых, вы присваиваете array элемент другого размера в зависимости от конструктора. Хорошей практикой является выполнение assert при попытке доступа к члену массива для проверки индекса не выходит за пределы.

Далее, в вашем setCoef(...) вы копируете содержимое старого массива в новый, и если новый меньше старого, вы получаете нарушение прав доступа:

...
void Poly::setCoeff(int coeff, int exp) {
    int* newarray = new int[(abs(exp)) + 1];

    for (int i = 0; i <= (abs(exp));i++) {
        newarray[i] = 0;
    }

    for (int i = 0; i <= this->largest_exponent;i++) {
        newarray[i] = this->array[i];  // HERE <<<<<<<<<<<<
    }
    ...

Также вы не delete[] ваш предыдущий array, когда вы перераспределяете его setCoef(...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...