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;
}

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.

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

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 2 Years Ago by Ancient Dragon

This article has been dead for over six months. Start a new discussion instead.