I have an assignment in which I have to create a class called IntegerSet. The point is that it creates sets of integers. If an integer is present in the set, then that number has a 1 in its place in the array set, and a 0 if not. I have been studying dynamic memory allocation and so I think I need that part to stay. However, when I run the program, it allows me to input up to the second number. It then comes up with an error, something about heap memory corruption. I don't know how to fix it at all. I guess that maybe the memory scope in some of my methods might be off a bit. Or some other issue with my dynamic memory allocation.
Since in my class, we are studying dynamic memory allocation, pointers, and pass-by-reference, I would like to be able to keep those aspects in the program and learn how to make them work correctly.
Here is the .h file:
#ifndef INTEGERSET_H
#define INTEGERSET_H
class IntegerSet
{
private:
int *setArray;
int setSize;
public:
IntegerSet(int = 0);
IntegerSet(const IntegerSet&);
~IntegerSet();
IntegerSet* unionOfSets(const IntegerSet&) const;
IntegerSet* intersectionOfSets(const IntegerSet&) const;
bool insertElement(int);
bool deleteElement(int);
void printSet() const;
bool isEqual(const IntegerSet&) const;
};
#endif
Here is the .cpp file:
#include "IntegerSet.h"
#include <iostream>
using namespace std;
//Constructor
IntegerSet::IntegerSet(int size)
{
setArray = new int[size];
setSize = size;
for (int i = 0; i < size; ++i)
{
setArray[i] = 0; //Initializes the set to 0;
}
}
//Copy constructor
IntegerSet::IntegerSet(const IntegerSet &setToCopy)
: setSize(setToCopy.setSize)
{
setArray = new int[setSize];
for (int i = 0; i < setSize; ++i)
{
setArray[i] = setToCopy.setArray[i];
}
}
//Destructor
IntegerSet::~IntegerSet()
{
delete[] setArray;
}
//Prints set
void IntegerSet::printSet() const
{
for (int i = 0; i < setSize; ++i)
{
if(setArray[i] == 1)
cout << i + 1 << " ";
}
}
//Unites two sets into a new set
IntegerSet* IntegerSet::unionOfSets(const IntegerSet &otherSet) const
{
IntegerSet* thirdSet = new IntegerSet; //Dynamically allocates a new set
for (int i = 0; i < setSize; ++i)
{
if (this->setArray[i] == 1 || otherSet.setArray[i] == 1)//
{
thirdSet->insertElement(i); //Assigns the new set the united sets' values
}
}
return thirdSet; //Returns pointer to new resulting set.
}
//Inyersects two sets to the new set
IntegerSet* IntegerSet::intersectionOfSets(const IntegerSet &otherSet) const
{
IntegerSet* extraSet = new IntegerSet;
for (int i = 0; i < setSize; ++i)
{
if (setArray[i] == 1 && otherSet.setArray[i] == 1)
{
extraSet->insertElement(i); //Assigns the new set the intersecting sets' values
}
}
return extraSet; //Returns pointer to the new resulting set
}
//Inseerts new element
bool IntegerSet::insertElement(int k)
{
if (k <= setSize && k >= 0)
{
setArray[k] = 1;
return true;
}
else
return false;
}
//Deletes element
bool IntegerSet::deleteElement(int m)
{
if (m <= setSize && m >= 0)
{
setArray[m] = 0;
return true;
}
else
return false;
}
//Checks if two sets are equal
bool IntegerSet::isEqual(const IntegerSet &otherSet) const
{
for (int i = 0; i < setSize; ++i) //Access each element
{
if (setArray[i] != otherSet.setArray[i])
return false; //If even one element is not equal then the sets cannot be equal
}
return true; //If after the loop finds none of the elements are equal, then the sets must be equal
}
And here is the client test file:
#include "IntegerSet.h"
#include <iostream>
using namespace std;
int main()
{
int input; //User input
IntegerSet set1(3);
IntegerSet set2(3);
IntegerSet* set3 = nullptr;
IntegerSet* set4 = nullptr;
cout << "Enter a number between 1 and 3 to add to the first set: ";
cin >> input;
while (!set1.insertElement(input - 1))
{
cout << "\nThat is an invalid number. Please enter a number between 1 and 3: ";
cin >> input;
}
set1.insertElement(input - 1);
cout << "Enter a number between 1 and 3 to add to the first set: ";
cin >> input;
while (!set2.insertElement(input - 1))
{
cout << "\nThat is an invalid number. Please enter a number between 1 and 3: ";
cin >> input;
}
set2.insertElement(input - 1);
cout << "Set 1 is: ";
set1.printSet();
cout << "\nSet 2 is: ";
set2.printSet();
cout << endl;
set3 = set1.unionOfSets(set2);
set4 = set1.intersectionOfSets(set2);
cout << "The union of Set 1 and Set 2: " << endl;
cout << "Set 3 - {"; // I tried using this first:
set3->printSet(); //cout << "Set 1 - {" << set1.printSet() << "}" << endl;
cout << "}" << endl; // But it wouldn't work because the second << was being show as an ambiguity error
cout << "The intersection of Set 1 and Set 2: " << endl;
cout << "Set 4 - {";
set4->printSet(); //Same formatting reasons as above.
cout << "}" << endl;
if (set1.isEqual(set2))
cout << "Set 1 and Set 2 are equal" << endl;
else
cout << "Set 1 and Set 2 are not equal" << endl;
set3->deleteElement(1);
set4->deleteElement(1);
cout << "After removing 2 from Set 3 and Set 4" << endl
<< "Set 3 is now - {";
set3->printSet();
cout << "}" << endl;
cout << "Set 4 is now - {";
set4->printSet();
cout << "}" << endl;
delete set3;
delete set4;
system("PAUSE");
return 0;
}
The program is supposed to ask the user for two integers, just to test. It would then do some examples of unions and intersections of the sets they create. What ended up happening was that it would get to the second input and then come up with a heap corruption error, and the strings showing the union sets do not print.