Ok, so I have been thinking about this for days and I am really unsure how to approach these problems. So I need to do the following:
create a union method (i.e. union(set)) that creates a union for two sets. This method should somehow invoke the element method, a method whose specifications are mentioned below
create an operator overloaded method (+) that represents the union of sets (not sure why they are different, but that's what the specifications ask for). This method must also invoke the union method
element (int) that checks if the elements are a part of the set, I have a method below, but I am not sure if it's right
operator overload method that adds an element to a new set
If you could address at least one of these, i would greatly appreciate it, I am really struggling to understand how to address these specifications. Thanks so much for your help!
#ifndef SET_H
#define SET_H
#include <iostream>
#include <cstdlib>
#include <iomanip>
using namespace std;
class Set{
friend ostream &operator<< ( ostream &, const Set &);
friend istream &operator>> ( istream &, Set &);
public:
Set ( int = DEFAULTSIZE ); //default constructor
Set ( const Set & ); //copy constructor
Set ( int [], int, char ); //constructor passing array of integers, size, name of set
~Set(); //destructor
//assignment operator
const Set &operator= ( const Set &);
//equality operator
bool operator== ( const Set & ) const;
//inequality operator
bool operator!= ( const Set &s1) const{
return !(*this == s1);
}
//subscript operators
int &operator[] ( int );
int operator[] ( int ) const;
//methods to find union, intersection, and difference of sets
Set Union ( Set & );
Set Intersect ( Set & );
Set Difference ( Set & );
Set operator+ ( Set & ); //to represent union of two sets
Set operator^ ( Set & ); //to represent intersection of two sets
Set operator- ( Set & ); //to represent difference between two sets
bool element ( int );
private:
static const int DELIM = -999; // delimiter to signal end of input
static const int DEFAULTSIZE = 10;
int numOfElements;
int psize; //physical size of array
int *set; //pointer array to represent set
};
#endif
//SOURCE FILE
//default constructor
Set::Set ( int s ){
if ( s > 0 )
psize = s;
else
psize = DEFAULTSIZE;
//allocate an array of specified size
set = new int[ psize ];
if(!set) {
//send an error is system cannot allocate memory
cout << "Cannot Allocate Memory, exiting program... " << endl;
exit (1);
}
for ( int i = 0; i < psize; i++){
set[i] = 0;
numOfElements = 0;
}
}
//copy constructor
Set::Set ( const Set &setToCopy): psize(setToCopy.psize){
set = new int[psize];
if(!set){
cout << "Cannot Allocate Memory, exiting program..." << endl;
exit (1);
}
for (int i = 0; i < psize; i++ ){
set[i] = setToCopy.set[i];
numOfElements = psize;
}
}
Set::~Set(){
if (set)
delete [] set;
set = NULL;
}
const Set &Set::operator= ( const Set &s1 ){
if ( &s1 != this){
if (numOfElements != s1.numOfElements){
delete [] set;
psize = numOfElements;
set = new int [psize];
if (!set){
cout << "Cannot Allocate memory, exiting program..." << endl;
exit (1);
}
}
}
//assign contents of the array on the right to the contents of the array on the left
for ( int i = 0; i < psize; i++ ){
set[i] = s1.set[i];
numOfElements = psize;
}
return (*this);
}
bool Set::operator== ( const Set &s1 ) const {
bool validate = true;
if ( numOfElements == s1.numOfElements ){
for ( int i = 0; i < numOfElements; i++){
if ( set [i] != s1.set[i] ){
validate = false;
break;
}
}
}
return (validate);
}
int &Set::operator[]( int subscript ){
if ( subscript < 0 || subscript >= psize ) {
cout << " Error, exiting program... " ;
exit (1);
}
return set[subscript];
}
bool Set::element ( int n ) {
bool validate = false;
for ( int i = 0; i < psize; i++){
if ( set[i] = n )
validate = true;
}
return (validate);
}
Related
I am creating a code for a sparse matrix, basically for adding two sparse matrices.
And now it's not working. showing some error with return NULL.
When checking for the condition that if the dimensions of the matrix are not the same, it will not execute the program as the condition will be false and it will return NULL but it's showing an error there.
#include<iostream>
using namespace std;
class Element{
public:
int i;
int j;
int x;
};
class Sparse{
private:
int m;
int n;
int num;
Element *ele;
public: // constructor
Sparse(int n ,int m , int num){
this->n = n;
this->m = m;
this->num = num;
ele = new Element[this->num];
}
~Sparse(){ // destructor
delete []ele;
}
//Global functions for insertion and extraction
Sparse operator+(Sparse &s);
friend istream & operator>>(istream &is , Sparse &s); // Insertion operator
friend ostream & operator<<(ostream &os , Sparse &s); // Extraction operator
};
Sparse Sparse::operator+(Sparse &s)
{
int i , j , k;
if(m!=s.m || n!=s.n)
return NULL;
Sparse *sum = new Sparse(m,n,num+s.num);
i=j=k=0;
while(i<num && j<s.num){
if(ele[i].i < s.ele[j].i){
sum->ele[k++] = ele[i++];
}else if(ele[i].i > s.ele[j].i){
sum->ele[k++] = s.ele[j++];
}else{
if(ele[i].j < s.ele[j].j){
sum->ele[k++] = ele[i++];
}else if(ele[i].j > s.ele[j].j){
sum->ele[k++] = s.ele[j++];
}else{
sum->ele[k]=ele[i];
sum->ele[k++].x = ele[i++].x +s.ele[j++].x;
}
}
}
for(;i<num;i++)sum->ele[k++] = ele[i];
for(;j<s.num;j++)sum->ele[k++] = s.ele[j];
sum->num = k;
return *sum;
}
// void read()
istream & operator>>(istream &is , Sparse &s)
{
cout<<"Enter non zero elements:";
for(int i=0;i<s.num;i++){
cin>>s.ele[i].i>>s.ele[i].j>>s.ele[i].x;
}
return is;
}
// void Display()
ostream & operator<<(ostream &os , Sparse &s)
{
int k = 0;
for(int i= 0; i<s.m;i++){
for(int j=0 ; j<s.n; j++){
if(s.ele[k].i ==i && s.ele[k].j ==j){
cout<<s.ele[k++].x<<" ";
}else{
cout<< "0 ";
}
}
cout<<endl;
}
return os;
}
int main(){
Sparse s1{5,5,5};
Sparse s2{5,5,5};
// s1.read();
// s1.Display();
cin>>s1;
cin>>s2;
Sparse sum=s1+s2;
cout<<"Enter First Matrix:"<<endl<<s1;
cout<<"Enter Second Matrix"<<endl<<s2;
cout<<"Sum Matrix"<<endl<<sum;
return 0;
}
If you go and see the definition of NULL, you will notice that
#define NULL 0
The NULL is replaced by a 0, which is a long int.
In some programming languages, like Java and C#, objects are passed around as pointers, and therefore you can just assign them to null. C++, however, somehow works similar to a struct -- it is passed by value.
Sparse Sparse::operator+(Sparse &s) means that the operator will return a Sparse type. As classes are passed by value, it will return the object's data, a series of bytes. That means you can't just return a NULL to indicate that the concatenation had failed.
An alternative would be to throw an exception. You can also rewrite the operator to a method that returns a Sparse*, a pointer to a Sparse.
Sparse* addSparse(Sparse s1, Sparse s2) {
if(s1.m != s2.m || s1.n != s2.n)
return NULL;
// add them together
}
That way, the caller can check if the concatenation is successful by checking the returned value.
Sparse* result = addSparse(s1, s2);
if(result != NULL) {
// Consume the result
}
// Handle it
I'm currently in the second sequence of a C++ course. I'm building my own string class using c-strings & dynamic memory.
I have a majority of my code working. I'm reading in a file and putting each word in a vector of my class type "ATString". We are supposed to combine 5 of the words read in, into a jumbo word, and putting that into another vector. When I use the debugger to step through my code, I see the words combining and it is copying the words over to the new ATString variable "tempJumbo". After a few lines run, the program crashes and tells me my program has triggered a breakpoint, leaving me on line 96 of the addition operator function.
Here the operator+ definition:
ATString ATString::operator+ (ATString& string1) {
int newSize = length() + string1.length();
ATString newString;
if (newSize > 20) { // increase capacity if size is greater than 20 characters
newString.increase_cap();
}
else {
cap = 20;
}
newString.strPtr = new char[newString.cap];
newString.end = newSize;
for (int i = 0; i < length(); i++) {
newString[i] = strPtr[i];
for (int j = length(); j < newSize; j++) {
newString[j] = string1.strPtr[j-end];
}
return newString;
}
And here is main, reading in the file and attempting to combine the words into a jumbo word.
int main() {
vector<ATString> words(100);
vector<ATString> lines(100); // calls default constructor 100 times
ifstream fin("infile3.txt");
int index = 0;
int wordCount = 0;
//READ
if (fin.fail()) {
cout << "Couldn't open infile2.txt" << endl;
system("pause");
exit(1);
}
while (!fin.eof()) {
fin >> words[index];
index++;
}
wordCount = index;
words.resize(wordCount);
//COMBINE 5 WORDS INTO ONE JUMBO
ATString tempJumbo;
int j = 0;
for (int i = 0;i < wordCount; i++) {
tempJumbo = words[i] + words[i+1] + words[i+2] + words[i+3] + words[i+4];
lines[j] = tempJumbo; // putting big word into lines vector
tempJumbo = " "; //resetting variable to hold jumbo word?
i = i + 4;
j++;
if (i == wordCount) {
break;
}
}
return 0;
}
I am also have issues with the destructor I wrote.. it's pretty simple and when I have this activated, it triggers an error as well and crashes the program. Not sure what is going here.
ATString::~ATString() {
delete strPtr;
}
Below is my header file:
#ifndef ATSTRING_H
#define ATSTRING_H
#include <istream>
using namespace std;
class ATString {
public:
ATString();// default constructor
ATString(const char* cstr); // cstring constructor
ATString(const ATString& argstr); // copy constructor
~ATString(); // destructor
ATString& operator = (const ATString& objToCopy); // assignment operator =
ATString operator + (ATString& string1); // addition operator +
int length() const;
int capacity() const;
void increase_cap();
char& operator [] (int index); // indexing operator
const char& operator [] (int index) const; // const indexing operator
bool operator <(const ATString& argstr) ;
bool operator > (const ATString& argstr) ;
bool operator ==(const ATString& argstr);
friend istream& operator >> (istream& inStrm, ATString& argstr); // extraction operator
friend const ostream& operator << (ostream& outStrm, const ATString& argstr); // insertion opertator
private:
char* strPtr;
int end;
int cap;
int compareTo(const ATString& argStr);
};
#endif
THANK YOU!
How big is your input file? If it is 100 words or more, then your index runs out of bounds on the line, when i = 96, i.e. trying to get words[100] element.
tempJumbo = words[i] + words[i+1] + words[i+2] + words[i+3] + words[i+4];
I have this constructor from my custom string class ( for homework ) that receives char array as parameter. Then each time it receives a char array like this one: "Hello", valgrind reports "Conditional jump or move depends on uninitialized value", but the programme still works correctly. I tried several ways of taking the length and still got this problem. So is there a correct way to get the length of char array like the one I mentioned above, without valgrind having problems with it?
CString::CString ( const char * charArray )
{
index = 0;
arrAlocated = 0;
string = nullptr;
int length = strlen ( charArray );
for ( index = 0; index < length; ++index )
{
if ( index == arrAlocated )
{
realloc ( string, index, arrAlocated );
}
string [ index ] = charArray [ index ];
}
string [ index ] = 0;
}
This is the class declaration.
class CString
{
public:
int arrAlocated;
int index;
char * string;
CString ( );
CString ( const char * array);
CString ( const CString & other );
~CString ( );
void clear ( );
CString & operator = ( const CString & other );
bool operator == ( const CString & other ) const;
char operator [] ( int i ) const
{
return string[ i ];
}
void realloc ( char *& string, int index, int & arrAlocated );
int length ( )
{
return strlen ( string );
}
friend ostream & operator << ( ostream & os, const CString & o )
{
for ( int i = 0; i < o.index; ++i )
{
os << o.string [ i ];
}
return os;
}
};
And here is my realloc function
void CString::realloc ( char *& string, int index, int & arrAlocated )
{
arrAlocated += 10;
arrAlocated *= 2;
char * newArray = new char [ arrAlocated ];
for ( int i = 0; i < index; ++i )
{
newArray [ i ] = string [ i ];
}
delete [] string;
string = newArray;
}
You aren't assigning the return value of realloc. string remains null the entire time.
(Also, you know the size you'll need to start from the beginning. Just call malloc once.)
i am trying to overload operators << >> != == = and [] for Array class.
The app crashes on run, though no compilation errors are shown.
what could possibly be wrong? IDE used dev c++
Here's array.h
#ifndef ARRAY_H
#define ARRAY_H
#include <iostream>
using namespace std;
class Array{
friend ostream & operator << ( ostream &, const Array & );
friend istream & operator >> ( istream &, Array &);
private:
int size;
int * ptr;
public:
Array ( int = 10 );
Array ( const Array & ); //copy constructor
~Array ();
const Array &operator=( const Array & );
bool operator == ( const Array & ) const;
bool operator != ( const Array & ) const;
const int operator [] (int) const;
int getSize() const;
};
#endif
and now array.cpp
#include <iostream>
using namespace std;
#include "array.h"
Array::Array (int sze ){ //default constructor edited
size = (sze > 0 ? sze : 10);
ptr = new int [ size ];
for (int i = 0; i < size; i++)
ptr[ i ] = 0; //initial values
}
Array::Array (const Array & arr ): size(arr.size){
ptr = new int [size];
for ( int i = 0; i< size; i++)
ptr [ i ] = arr.ptr [ i ];
}
Array::~Array(){
delete [] ptr;
}
const Array &Array :: operator= ( const Array & right){//IMPO
if(&right != this){ //edited self assignment test
if(size != right.size){//diff sized arrays
delete [] ptr; //reclaim space
size = right.size;
ptr = new int [ size ]; //space created
}
}
for(int i=0; i<size; i++)
ptr[ i ] = right.ptr[ i ];
return *this; //enables cascading a=b=c
}
bool Array::operator == ( const Array & right) const{
if ( size != right.size )
return false;
for ( int i =0; i < size; i++ ){
if ( ptr [ i ] != right.ptr[ i ] )
return false;
}
return true;
}
bool Array::operator != ( const Array & right ) const{ //edited
return ! (*this == right);
}
const int Array::operator [] (int subscript) const{
if(subscript >=0 && subscript < size)
return ptr[ subscript ];
}
int Array::getSize() const{ return size; }
//friend functions not in .h
ostream & operator << ( ostream & output, const Array & array){
for (int i = 0; i < array.size; i++)
output << array.ptr[i] ;
}
istream & operator >> ( istream & input, Array & array){
for (int i = 0; i < array.size; i++)
input >> array.ptr[i];
}
now main.cpp
#include <cstdlib>
#include <iostream>
#include "array.h" // " " not <>
using namespace std;
int main(int argc, char *argv[])
{
Array a1(7),a2 (-1),a4; //changed a2
cout<<"Input "<<a1.getSize()<<" integers for Array object a1 and "<<a2.getSize()<<" integers for Array objecta2\n";
cin>>a1>>a2;
cout<<"a1 and a2 are\n";
cout<<a1<<endl<<a2;
cout<<"a1!=a2 : "<<(a1!=a2)<<endl;
cout<<"a1 ==a2: "<<(a1==a2)<<endl;
cout<<"Printing a1[5] : "<<a1[5]<<endl;
Array a3(a1);
a4 = a3;
system("PAUSE");
return EXIT_SUCCESS;
}
You have to reserve memory for ptr in the constructor.
Array::Array (int size ){ //default constructor
size = (size > 0 ? size : 10);
ptr = new int [size]; // ADD THIS LINE
for (int i = 0; i < size; i++)
ptr[ i ] = 0; //initial values
}
There are some other problems with your code that are not the direct source of the crash but are worth noting:
Array::operator != is defined in terms of itself. It should be similar to operator==, or you can re-use it with
if( *this == right )
return false;
return true;
Array::operator [] should probably throw an exception if the index is out of bounds. Currently it just returns garbage memory.
Inside Array::Array (int size ) the assignment to size assigns to the parameter, not to the member. Change the first line to:
this->size = (size > 0 ? size : 10);
operator<< and operator>> should return output and input, respectively.
ostream & operator << ( ostream & output, const Array & array){
for (int i = 0; i < array.size; i++)
output << array.ptr[i] ;
return output;
}
Also, you have en error in your implementation of operator != at line:
if ( *this != right ) - recursive definition, so, stack overflow.
You have 2 errors in your default constructor:
1) You do not allocate memory for ptr and you try to initialize it, this is certainly an error and cause an undefined behavior, so if you have some invalid value in ptr you may get a segmentation fault or worse you may overwrite value of some of your internal variables!
2) Name of variable of the default constructor is size and size = (size > 0 ? size : 10); change value of local variable size not the size member of your class, and because of that your size member will remain uninitialized and any use of that is illegal and you may still get exceptions like segmentation fault(for example size may be 7476327436 that certainly is far beyond end of your array.
and beside that you have 1 error in your operator !=, since you have if ( *this != right ) and that will use operator != for comparison, and this is a recursive function in all cases and you will get a stack overflow exception, so if you want to check for exact pointers use if ( this != right ) instead of that.
I don't fully check your code first time that I see it, but you have some other errors in your code and I don't know how you even compile it, In multiple places you do not provide return value for your function. Please remember Never ignore compiler warnings there exist to help you correct your programming errors:
const int Array::operator [] (int subscript) const{
if(subscript >=0 && subscript < size)
return ptr[ subscript ];
// If not what should I do?? add a return value here, this is a warning
// since compiler think somehow you know that your code never reach here
// but do you really know??
return 0;
}
ostream & operator << ( ostream & output, const Array & array){
for (int i = 0; i < array.size; i++)
output << array.ptr[i] ;
// You say that your function return an ostream& but where is it??
// this is an error so compiler have nothing to return instead of you!
// And if your compiler does not generate an error possibly it return
// junk value that will cause an error!!
return output;
}
istream & operator >> ( istream & input, Array & array){
for (int i = 0; i < array.size; i++)
input >> array.ptr[i];
// again you forget to return an istream& and again this is an error
return input;
}
but beside that I see no error in your code and it should run with no error
I'm having a problem assigning pointers to an array of pointers in my program. I have it setup so that the function accepts a pointer as an argument and I tried to assign that pointer to an index of the array. It compiles fine, but it does not run, I get a segfault.
The error comes from EventHeap::push, the first line in the function.
You guys have any ideas?
I appreciate the help.
Edit: I'll post the specific problem right down below, but I'll just leave the code just in case below it :D
The segfault occurs in the push function, first line.
void ModemSimV2::nextCall( int delta ){
static int nextCallTime = 0;
static int userNum = 0;
Event *e;
e = new Dialin( userNum++, nextCallTime );
eventSet->push( e );
nextCallTime += delta;
}
//push function takes a pointer to an Event and puts into the array
void EventHeap::push( Event *e ) {
array[size] = e;
reIndex( size );
size++;
}
Source:
// ModemSimV2.cpp
//
// #author David Harrigan
// dtk24
//
// 4/10/2012
//
#include "ModemSimV2.h"
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx
//++++++++++++++++++++++++++ ModemSimV2 +++++++++++++++++++++++++++
// Constructor for ModemSim.
ModemSimV2::ModemSimV2( int modems, double avgLen, int callIntrvl )
: freeModems( modems ), avgCallLen( avgLen ),
freqOfCalls( callIntrvl ), r( (int) time( 0 ) )
{
nextCall( freqOfCalls ); // Schedule first call
}
// Place a new DIAL_IN event into the event queue.
// Then advance the time when next DIAL_IN event will occur.
// In practice, we would use a random number to set the time.
void ModemSimV2::nextCall( int delta ){
static int nextCallTime = 0;
static int userNum = 0;
Event *e;
e = new Dialin( userNum++, nextCallTime );
eventSet->push( e );
nextCallTime += delta;
}
// Run the simulation until stopping time occurs.
void ModemSimV2::runSim( int stoppingTime ){
Event *e;
int i = 0;
while( ! eventSet->empty( ) ){
e = eventSet->pop();
if ( e->getTime() > stoppingTime )
break;
if ( e->process( *this ) )
eventSet->push( e );
nextCall( freqOfCalls );
i++;
}
}
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx
//+++++++++++++++++++++++++++++ Event +++++++++++++++++++++++++++++
//Constructor for event
Event::Event(){
}
//copy constructor
Event::Event( const Event &e ) {
*this = e;
}
//virtual destructor
Event::~Event( ) {
}
//operator overloads
bool Event::operator > ( const Event & rhs ) const {
return time > rhs.time;
}
bool Event::operator < ( const Event & rhs ) const {
return time < rhs.time;
}
bool Event::operator <= ( const Event & rhs ) const {
return time < rhs.time;
}
bool Event::operator != ( const Event & rhs ) const {
return time != rhs.time;
}
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx
//+++++++++++++++++++++++++++++ Dialin +++++++++++++++++++++++++++++
//inhereited constructor
Dialin::Dialin (int name, int tm )
: time( tm ), who( name ) {
return;
}
//copy constructor
Dialin::Dialin ( const Dialin &d ) {
*this = d;
}
//destructor
Dialin::~Dialin( ) {
}
//bool process - unfinished
bool Dialin::process( ModemSimV2 &m ) {
cout << "User " << who << " dials in at time "
<< time << endl;
if( m.freeModems > 0 ) {
m.freeModems--;
int howLong = r.negExp( m.avgCallLen );
cout << " and connects for " << howLong <<
" minutes " << endl;
time += howLong;
return true;
}
else {
cout << "but gets busy signal" << endl;
return false;
}
}
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx
//++++++++++++++++++++++++++++ Hangup +++++++++++++++++++++++++++++
//inhereited constructor
Hangup::Hangup (int name, int tm )
: time( tm ), who( name ) {
return;
}
//copy constructor
Hangup::Hangup ( const Hangup &h ) {
*this = h;
}
//destructor
Hangup::~Hangup ( ) {
}
//bool process - unfinished
bool Hangup::process( ModemSimV2 &m ) {
m.freeModems++;
cout << "User " << who << " hangs up at time "
<< time << endl;
return false;
}
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx
//++++++++++++++++++++++++++ EventHeap ++++++++++++++++++++++++++++
//EventHeap constructor
EventHeap::EventHeap( ) {
array = new Event*[1];
size = 0;
}
//constructor
EventHeap::EventHeap( int numVals ) {
array = new Event*[numVals];
size = 0;
}
//push function takes a pointer to an Event and puts into the array
void EventHeap::push( Event *e ) {
array[size] = e;
reIndex( size );
size++;
}
//since this is a min-heap, it removes the smallest value in the array
Event* EventHeap::pop( ) {
Event *e = array[0];
array[0] = array[size - 1];
size--;
if( !empty( ) )
buildHeap(0);
return e;
}
//builds the heap once popped, to reorder the array
//
void EventHeap::buildHeap( int index ) {
int min;
if (getRight(index) >= size) {
if (getLeft(index) >= size)
return;
else
min = getLeft(index);
}
else {
if (array[getLeft(index)] <= array[getRight(index)])
min = getLeft(index);
else
min = getRight(index);
}
if (array[index] != 0 && array[index] > array[min]) {
Event *temp( array[min] );
array[min] = array[index];
array[index] = temp;
buildHeap(min);
}
}
//similar to buildHeap, but is called when a value is pushed to the array
//
void EventHeap::reIndex( int hole ) {
while( array[hole] != NULL && array[hole] < array[getParent( hole )] ) {
int pIndex = getParent( hole );
Event *temp( array[hole] );
array[hole] = array[pIndex];
array[pIndex] = temp;
hole = pIndex;
}
}
//returns true if empty
bool EventHeap::empty() const {
return ( size == 0 );
}
//returns the left child
int EventHeap::getLeft( int index ) const {
return ( index * 2 ) + 1;
}
//returns the right child
int EventHeap::getRight( int index ) const {
return ( index * 2 ) + 2;
}
//returns the parent
int EventHeap::getParent( int index ) const {
return ( index - 1 ) / 2;
}
Header:
// ModemSimV2.h
//
// #author David Harrigan
// dtk24
//
// 4/10/2012
//
#ifndef MODEM_SIM_V2_H
#define MODEM_SIM_V2_H
#include <queue>
#include <vector>
#include <functional> // for greater()
#include <climits> // for INT_MAX
#include <iostream>
#include "random.h"
using namespace std;
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx
//++++++++++++++++++++++++++ ModemSimV2 +++++++++++++++++++++++++++
class EventHeap;
class ModemSimV2 {
public:
ModemSimV2( int modems, double avgLen, int callIntrvl );
// Add a call to eventSet at the current time,
// and schedule one for delta in the future.
void nextCall( int delta );
// Run the simulation
void runSim( int stoppingTime );// = INT_MAX );
friend class Event;
friend class Dialin;
friend class Hangup;
private:
Random r; // A random source
EventHeap *eventSet; // Pending events
// Basic parameters of the simulation
int freeModems; // Number of modems unused
const double avgCallLen; // Length of a call
const int freqOfCalls; // Interval between calls
};
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx
//+++++++++++++++++++++++++++++ Event +++++++++++++++++++++++++++++
class Event{
protected:
int who; // the number of the user
int time; // when the event will occur
friend class ModemSimV2;
Random r;
public:
Event( );
Event( const Event &e );
virtual ~Event( );
bool operator > ( const Event & rhs ) const;
bool operator < ( const Event & rhs ) const;
bool operator <= ( const Event & rhs ) const;
bool operator != ( const Event & rhs ) const;
int getTime( ) { return time; };
virtual bool process( ModemSimV2 &m ) = 0;
};
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx
//+++++++++++++++++++++++++++++ Dialin ++++++++++++++++++++++++++++
class Dialin : public Event {
public:
Dialin( int name = 0, int tm = 0 );
Dialin( const Dialin &d );
~Dialin( );
virtual bool process( ModemSimV2 &m );
private:
int who;
int time;
};
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx
//+++++++++++++++++++++++++++++ Hangup ++++++++++++++++++++++++++++
class Hangup : public Event {
public:
Hangup( int name = 0, int tm = 0 );
Hangup( const Hangup &h );
~Hangup( );
virtual bool process( ModemSimV2 &m );
private:
int who;
int time;
};
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx
//++++++++++++++++++++++++++ EventHeap ++++++++++++++++++++++++++++
class EventHeap{
public:
EventHeap();
EventHeap( int numIndex );
bool empty( ) const;
const int & findMin( ) const;
void push( Event *x );
Event * pop();
private:
int size; // Number of elements in heap
Event **array; // The heap array
void buildHeap( int index );
void reIndex( int hole );
int getLeft( int index ) const;
int getRight( int index )const;
int getParent( int index )const;
};
#endif
Here is a clue:
e = new Dialin( userNum++, nextCallTime );
eventSet->push( *e );
You are allocating a new object and pushing a copy of it.
Another clue:
// Constructor for ModemSim.
ModemSimV2::ModemSimV2( int modems, double avgLen, int callIntrvl )
:
r( (int) time( 0 ) ),
// what about eventSet?
freeModems( modems ),
avgCallLen( avgLen ),
freqOfCalls( callIntrvl ),
{
nextCall( freqOfCalls ); // Schedule first call
}
eventSet is declared as an EventHeap* in ModemSimV2, however you do not initialize it in the constructor. Therefore when you first use it a segfault occurs.
ModemSimV2::ModemSimV2( int modems, double avgLen, int callIntrvl )
: freeModems( modems ), avgCallLen( avgLen ),
freqOfCalls( callIntrvl ), r( (int) time( 0 ) )
{
eventSet = new EventHeap(); // <-- missing this initialization
nextCall( freqOfCalls ); // Schedule first call
}
Also to avoid memory leaks, you will need a destructors in ModemSimV2 and EventHeap to free the memory you allocate.