0

Hi All,

I am having trouble trying to locate the problem with this code. When I run it I get the follow error "First-chance exception at 0x0FADA9E8 (msvcr120d.dll) in ConsoleApplication2.exe: 0xC0000005: Access violation reading location 0xCCCCCCC0." It seems to show an error on the dbgdel.cpp but I am completley lost now so if anyhow has any idea why it's doing it that would be great.
Thanks in advance.
Here is my code

#include <iostream>
#include <string>
#include <fstream>
using namespace std;

// Error codes
enum { OK, FILTER_TOO_LONG, ALLOC_ERR, ACCESS_ERR };

// Name of the file that is used to save and load data values and filter values
const string filename = "data.txt";

// Class that represents the data.
// Provides array-like access.
class Data {
public:
    //Construct empty Data. 
    Data() : Values(0), Length(0) {};
    //~Data() { delete[] Values; };
    Data(const Data& d) {
        alloc(d.length());
        for (unsigned long CountData = 0; CountData < d.length(); ++CountData) {
            Values[CountData] = d[CountData];
        }
    };
    Data& operator=(const Data& d) {
    if (this != &d) {
            alloc(d.length());
            for (unsigned long CountData = 0; CountData < d.length(); ++CountData) {
                Values[CountData] = d[CountData];
            }
    }
        return *this;
    };

    // The amount of items in the Data.
    // Returns: amount of items    
    unsigned long length() const { return Length; };
    // Check whether the Data has any items.
    // Returns: true - if Data has items
    //          false - if Data is empty
    bool valid() const { return Length != 0 && Values; };
    // Allocate memory to store given number of items.
    // Arguments:
    //   (1) number of items
    // Returns: nothing
    // Throws an exception if memory cannot be allocated.
    void alloc(unsigned long length) {
        if (Values) delete[] Values;
        Values = new double[length];
        if (!Values)
            throw (int)ALLOC_ERR;
        Length = length;
    };
    // Set certain value in the Data.
    // Arguments:
    //   (1) index of value to access
    // Returns: value
    // Throws an exception when index is not valid.
    double& operator[](size_t i) {
        if (i < 0 || i >= Length)
            throw (int)ACCESS_ERR;
        return Values[i];
    };
    // Get certain value in the Data.
    // Arguments:
    //   (1) index of value to access
    // Returns: value
    // Throws an exception when index is not valid.
    const double& operator[](size_t i) const {
        if (i < 0 || i >= Length)
            throw (int)ACCESS_ERR;
        return Values[i];
    };
private:
    double* Values;
    unsigned long Length;
};

// Input data values.
// Arguments:
//   (1) input stream
//   (2) Data object where to store values
// Returns: input stream
istream& operator>>(istream& is, Data& data) {
    for (unsigned long CountData = 0; CountData < data.length(); CountData++) {
        is >> data[CountData];
    }
    return is;
}

// Output data values.
// Arguments:
//   (1) output stream
//   (2) Data object from which to read values
// Returns: output stream
ostream& operator<<(ostream& os, const Data& data) {
    for (unsigned long CountData = 0; CountData < data.length(); CountData++) {
        os << data[CountData] << "\n";
    }
    return os;
}

// Class that represents the filter.
// Provides array-like access to filter's values.
class Filter {
public:
    Filter() : Values(0), Length(0) {};
    ~Filter() { delete[] Values; };

    // The amount of items in the Filter.
    // Returns: amount of items    
    unsigned long length() const { return Length; };
    // Check whether the Filter has any items.
    // Returns: true - if Filter has items
    //          false - if Filter is empty
    bool valid() const { return Length != 0 && Values; };
    // Allocate memory to store given number of items.
    // Arguments:
    //   (1) number of items
    // Returns: nothing
    // Throws an exception if memory cannot be allocated.
    void alloc(unsigned long length) {
        if (Values) delete[] Values;
        Values = new double[length];
        if (!Values)
            throw (int)ALLOC_ERR;
        Length = length;
    };
    // Set certain value in the Filter.
    // Arguments:
    //   (1) index of value to access
    // Returns: value
    // Throws an exception when index is not valid.
    double& operator[](size_t i) {
        if (i < 0 || i >= Length)
            throw (int)ACCESS_ERR;
        return Values[i];
    };
    // Get certain value in the Filter.
    // Arguments:
    //   (1) index of value to access
    // Returns: value
    // Throws an exception when index is not valid.
    const double& operator[](size_t i) const {
        if (i < 0 || i >= Length)
            throw (int)ACCESS_ERR;
        return Values[i];
    };

    // Apply filter to the given data.
    // Arguments:
    //    (1) Data object to be filtered
    // Returns: new and filtered Data object
    // Throws an exception if number of filter values is bigger than number of data values.
    Data apply(const Data& in) const {
        if (length() > in.length())
            throw (int)FILTER_TOO_LONG;

        Data out;
        out.alloc(in.length() - length() + 1);

        // apply the filter to the data
        for (unsigned long CountData = 0; CountData < out.length(); CountData++) {
            out[CountData] = 0.0;
            for (unsigned long CountFilter = 0; CountFilter < length(); CountFilter++) {
                out[CountData] += in[CountData + CountFilter] * (*this)[CountFilter];
            }
        }
        return out;
    };
private:
    double* Values;
    unsigned long Length;
    Filter(const Filter& f);
    Filter& operator=(const Filter&);
};

// Input filter values.
// Arguments:
//   (1) input stream
//   (2) filter object where to store values
// Returns: input stream
istream& operator>>(istream& is, Filter& filter) {
    for (unsigned long CountData = 0; CountData < filter.length(); CountData++) {
        is >> filter[CountData];
    }
    return is;
}

// Output filter values.
// Arguments:
//   (1) output stream
//   (2) Filter object from which to read values
// Returns: output stream
ostream& operator<<(ostream& os, const Filter& filter) {
    for (unsigned long CountData = 0; CountData < filter.length(); CountData++) {
        os << filter[CountData] << "\n";
    }
    return os;
}

// Class that represents the application of a simple digital filter via command-line user interface.
class FilterApp {
public:
    // Default constructor serves as a main function, handling user input.
    FilterApp() {
        Filter Filter;
        Data OriginalData, FilteredData;
        char UserInput;
        unsigned long l;
        while (1) {
            menu();
            cout << "Enter your option: ";
            cin >> UserInput;
            cout << endl;

            // act on the user's input
            switch (UserInput) {
            case '1':
                cout << "How many data values do you wish to enter: ";
                cin >> l;
                OriginalData.alloc(l);
                cout << endl;
                cout << "Enter the data values one by one:" << endl;
                cin >> OriginalData;
                break;

            case '2':
                cout << "How many filter values do you wish to enter: ";
                cin >> l;
                Filter.alloc(l);
                cout << endl;
                cout << "Enter the filter values one by one:" << endl;
                cin >> Filter;
                break;

            case '3':
                if (Filter.valid() && OriginalData.valid()) {
                    try {
                        FilteredData = Filter.apply(OriginalData);
                    }
                    catch (int e) {
                        if (e == FILTER_TOO_LONG) { // not fatal error
                            cerr << "The filter must not be longer than the data" << endl;
                            break;
                        }
                        else if (e == ALLOC_ERR)
                            cerr << "Unable to allocate sufficient memory" << endl;
                        else if (e == ACCESS_ERR)
                            cerr << "Tried to access an array out of bounds" << endl;
                        else
                            cerr << "An unknown exception was thrown" << endl;
                        return;
                    }
                    cout << "Filter applied" << endl;
                }
                break;

            case '4':
                if (Filter.valid() && OriginalData.valid() && FilteredData.valid()) {
                    cout << "The filter values:\n" << Filter;
                    cout << "The original data values:\n" << OriginalData;
                    cout << "The filtered data values:\n" << FilteredData;
                }
                else {
                    cout << "Data have not yet been filtered" << endl;
                }
                break;

            case '5':
                if (Filter.valid() && OriginalData.valid()) {
                    save(Filter, OriginalData);
                    cout << "Finished saving data to file" << endl;
                }
                else {
                    cout << "Nothing to save, filter and data are empty" << endl;
                }
                break;
            case '6':
                load(Filter, OriginalData);
                cout << "Finished loading data from file" << endl;
                break;
            case '7':
                return;

            default:
                cout << "Invalid entry" << endl << endl;
                break;
            }
        }
    };
    // Display menu.
    // Returns: nothing.
    void menu() const {
        cout << endl;
        cout << "Filter Menu" << endl;
        cout << "-----------" << endl;
        cout << "1. Input data" << endl;
        cout << "2. Input filter values" << endl;
        cout << "3. Apply" << endl;
        cout << "4. Display data" << endl;
        cout << "5. Save data to file" << endl;
        cout << "6. Load data from file" << endl;
        cout << "7. Exit from the program" << endl << endl;
    };

    // Save filter and data values to the file.
    // Arguments:
    //    (1) Filter object
    //    (2) Data object
    // Returns: nothing.
    // Interrupts saving if the file cannot be opened.
    void save(const Filter& filter, const Data& data) const {
        fstream f;
        f.open(filename.c_str(), fstream::out);
        //if (!f.is_open()) {
        //  cerr << "Cannot open file " << filename << " for writing" << endl;
        //  return;
        //}
        f << filter.length() << "\n" << filter << "\n" << data.length() << "\n" << data << "\n";
        f.close();
    };

    // Load filter and data values from the file.
    // Arguments:
    //    (1) Filter object
    //    (2) Data object
    // Returns: nothing.
    // Interrupts loading if the file cannot be opened.    
    void load(Filter& filter, Data& data) const {
        fstream f;
        f.open(filename.c_str(), fstream::in);
        //if (!f.is_open()) {
        //  cerr << "Cannot open file " << filename << " for reading" << endl;
        //  return;
        //}
        f.seekg(0, std::ios::beg);
        unsigned long l, i;
        f >> l;
        filter.alloc(l);
        for (i = 0; i < l; ++i)
            f >> filter[i];
        f >> l;
        data.alloc(l);
        for (i = 0; i < l; ++i)
            f >> data[i];
        f.close();
    };
private:
    FilterApp(const FilterApp&);
    FilterApp& operator=(const FilterApp&);
};

int main() {
    FilterApp();
    return 0;
}
3
Contributors
4
Replies
18
Views
3 Years
Discussion Span
Last Post by AndrisP
0

Please post the steps you took to produce the error. Which menu items did you select, and what did you enter. Better yet, get a screenshop of the console window that contains all the information and post it here. I compiled your program with VC++ 2014 and it compiled without errors or warnings, then ran it, but I don't know what you did to get the error.

0

To recreate the error I build the program in Visual Studios 2013 and enter 0,1,3,6,3,1,0 for data, then -0.5,1,-0.5 for filter, then after applying the filter and then dispalying the results the results should be -0.5,-0.5,3,-0.5,-0.5. I tried it with different values and they all just crash as soon as I select 3.

I tested it on another compiler Dev C++ and it works perfectly so I am not sure if it is something with Visual Studios.

Thanks for your help

0

The problem is in Data constructor, you didn't initialize Values and Length so alloc() attempted to delete Values when it had a random value.

    Data(const Data& d) {
        Values = 0;
        Length = 0;
        alloc(d.length());
        for (unsigned long CountData = 0; CountData < d.length(); ++CountData) {
            Values[CountData] = d[CountData];
        }
    };
    Data& operator=(const Data& d) {
        if (this != &d) {
            alloc(d.length());
            for (unsigned long CountData = 0; CountData < d.length(); ++CountData) {
                Values[CountData] = d[CountData];
            }
        }
        return *this;
    };

Edited by Ancient Dragon

This article has been dead for over six months. Start a new discussion instead.
Be sure to adhere to our posting rules.