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