Multi Dimensional Array Implementation - c++

I've been working on some code for an assignment and I'm having an issue with nested templated types.
I need the following code to create a 3 element array of 3 element arrays (sort of like int b[3][3]):
Array< Array<int> > b(3);
Here are the relevant parts of my Array.h:
template <class T>
class Array{
public:
Array() : size(0){ data = NULL; }
Array(int s) : size(s) { data = new T[size]; }
Array(const Array & a) : size(a.length()) {
data = new T[a.length()];
for(int i = 0; i < a.length(); ++i)
data[i] = a[i];
}
~Array(){ delete[] data; }
T & operator[](int i) {
if (i >= 0 && i < size){
return data[i];
} else {
throw ArrayOutOfBounds(i);
}
}
T operator[](int i) const{
if (i >= 0 && i < size){
return data[i];
} else {
throw ArrayOutOfBounds(i);
}
}
Array<T> & operator=(const Array<T> &a){
if(this == &a) return *this;
delete[] data;
data = new T[a.length()];
for(int i = 0; i < a.length(); ++i)
data[i] = a[i];
size = a.length();
}
int length() const { return size; }
// Members
private:
int size;
T * data;
}
Update 6/1 the full driver code:
// Test driver for generic Array object with assignment and bounds checking
#include "Array.h"
int main() {
Array<int> a1(10);
for (int i = 0; i < a1.length(); ++i)
a1[i] = i * i;
Array<int> a2 = a1;
try {
for (int i = 0; i <= a2.length(); ++i)
cout << a2[i] << " ";
cout << endl;
}
catch (const ArrayOutOfBounds & e) {
cout << endl << "ArrayOutOfBounds index=" << e.index << endl;
}
Array< Array<int> > b(3);
for (int i = 0; i < b.length(); ++i) {
for (int j = 0; j < b[i].length(); ++j)
b[i][j] = i*b[i].length() + j;
}
for (int i = 0; i < b.length(); ++i) {
cout << "b[" << i << "]= ";
for (int j = 0; j < b[i].length(); ++j)
cout << b[i][j] << " ";
cout << endl;
}
Array<const char *> c(3);
c[0] = "moe"; c[1] = "curly"; c[2] = "larry";
Array<const char *> d(10);
d = c;
for (int i = 0; i < d.length(); ++i)
cout << "d[" << i << "]=" << d[i] << " ";
cout << endl;
return 0;
}
Expected output:
0 1 4 9 16 25 36 49 64 81
ArrayOutOfBounds index=10
b[0]= 0 1 2
b[1]= 3 4 5
b[2]= 6 7 8
d[0]=moe d[1]=curly d[2]=larry
Update 6/2
Per Guillaume's solution, here is the resize method I used:
Array<T> & resize(int newsize){
delete[] data;
data = new T[newsize];
size = newsize;
for(int i = 0; i < size; ++i)
init(data[i], size);
}
Recursive resizing works for higher dimensions, such as Array< Array< Array<int> > > q(3);

Based on the code, you pasted, this should not crash. Did you forget the destructor? You should have a destructor that deletes the memory. When you have one, you need to make sure that data is initialized to nullptr (or NULL) so it does not crash when deleting an empty array.
But your approach is confusing. Is Array size supposed to be determined at runtime or at compile time? int b[3][3] is determined at compile time. If you want that, you should make the size a template argument like std::array in C++11, see http://en.cppreference.com/w/cpp/container/array
If you want to detemrine the size at runtime, you'll need a resize method to determine the size of the the 2nd dimension.
EDIT:
Based on the driver code, you need to do something different in the constructor (passing the int to T if T is an Array). To be quite honest, this seems almost like a bug. This kind of specification makes it really hard to describe what the constructor do (call the default ctor for all types T except for Array)
I'd something like this:
private:
template <typename U>
void init(U&, int) {}
template <typename U>
void init(Array<U>& a, int sz)
{
a.resize(sz);
}
public:
Array(int s) : size(s) {
data = new T[size];
for (int i = 0 ; i < size; ++i) {
init(data[i], s);
}
}
It works but this is ugly. If you can use C++11, you can something nicer with std::enable_if

Related

OOP C++ language

I started learning OOP in C++. I try to solve a task like this:
Create a class - a list based on a one-size-fits-all array of integers. Assign a constructor, a destructor, the functions of adding an element to the top (end) of the list, selecting an element from the list by number, sorting the list, showing the elements of the list to the top and to the bottom of the list."
In the delete function, the compiler constantly knocks out the same error:
E0852 the expression must be a pointer to the full type of the object My_4_Project C:\Users\artem\source\repos\Project4\My_4_Project\Source.cpp
Here is my code:
#include <iostream>
#include <algorithm>
using namespace std;
class Array {
private:
int* a;
unsigned int size;
int b, c = 0, d;
public:
Array();
Array(int s);
~Array();
int& operator[](int index);
void setarray();
void getarray();
void add();
void delet();
void sort();
};
Array::Array() {
size = 10;
a = new int[size];
for (size_t i = 0; i != size; i++) {
a[i] = 0;
}
}
Array::Array(int s) {
if (s > 0) {
size = s;
a = new int[size];
for (size_t i = 0; i != size; i++) {
a[i] = 0;
}
}
else cout << "Size can't be negativ";
}
Array::~Array() {
delete[]a;
}
int& Array::operator[](int index) {
if (index <= size) {
return a[index];
}
}
void Array::setarray() {
for (size_t i = 0; i != size; i++) {
cin >> a[i];
}
}
void Array::getarray() {
for (size_t i = 0; i != size; i++) {
cout << a[i] << " ";
}
}
void Array::add()
{
/* ? ? ? */ ;
}
void Array::delet() {
cin >> b;
for (int i = 0; i < size; i++)
{
if (b == a[i])
c++;
if (c > 2) delete a[i];
}
cout << c;
}
void Array::sort() {
int temp;
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
for (int i = 0; i < size; i++) {
cout << a[i] << " ";
}
}
int main() {
cout << "Enter 10 number`s massive: ";
Array arr(10);
arr.setarray();
cout << endl;
arr.getarray();
cout << endl;
cout << "Sorted massive: ";
arr.sort();
cout << endl;
cout << "Witch symbol you wanna delete?: ";
arr.delet();
return 0;
}
The problem is that delete does not work as you think:
You can delete an object that you previously created with new (new returns a pointer, and delete expect that same pointer).
You can delete[] something that you previously created with new[]
But no mixing: you cannot delete an individual element when it was part of an array created with new[]
I will not do the exercise for you but the trick is to:
find the index of the duplicate element you want to get rid off,
copy every elements afterwards to one index before (i.e. a[j]=a[j+1], of course, making sure that j+1<size )
reduce the size by one.
So something like:
void Array::delet() {
cin >> b; // better put this in main() and pass it as argument
for (int i = 0; i < size; i++)
{
if (b == a[i])
{ // it'll be more than a single statement
c++;
if (c > 2) // found a duplicate
{ // NO delete a[i];
... // insert a loop to copy the next ones
// and reduce the size
... // EXTRA CAUTION: in this case the next element
// is again at offset i and not i++
}
}
}
cout << c; // ok, you can display the number of occurences counted
}

Destructor of dynamically allocated array causing Heap buffer error

So I have an assignement to write a version of the vector library without using it. I need to use dynamically allocated arrays, However their destructor is causing errors. Here is my code:
class orderedVector {
friend ostream& operator<<(ostream&, const orderedVector&);
friend istream& operator>>(istream&, orderedVector&);
public:
orderedVector(int = 9);
~orderedVector();
int getSize() const;
int getCapacity() const;
void doubleCapacity();
bool find(int) const;
void insert(int);
void remove(int);
void findSum(int);
private:
int size;
int capacity;
int* ptr;
};
orderedVector::orderedVector(int c) {
capacity = c;
size = 0;
ptr = new int[c];
}
orderedVector::~orderedVector() {
delete[] ptr;
}
int orderedVector::getSize() const {
return size;
}
int orderedVector::getCapacity() const {
return capacity;
}
void orderedVector::doubleCapacity() {
int newCapacity = capacity * 2;
orderedVector temp(capacity);
for (int i = 0; i < size; i++) {
temp.ptr[i] = ptr[i];
}
ptr = new int[newCapacity];
for (int i = 0; i < size; i++) {
ptr[i] = temp.ptr[i];
}
capacity = newCapacity;
}
bool orderedVector::find(int number) const {
for (int i = 0; i <= size; i++)
if (number == ptr[i])
return true;
return false;
}
void orderedVector::insert(int number){
if (find(number)) {
return;
}
if (size == capacity)
doubleCapacity();
if (size == 0)
ptr[0] = number;
else {
int checkpoint = size;
for (int i = 0; i < size; i++) {
if (number < ptr[i]) {
checkpoint = i;
break;
}
}
for (int i = size-1; i >= checkpoint; i--) {
ptr[i + 1] = ptr[i];
}
ptr[checkpoint] = number;
}
size++;
}
void orderedVector::remove(int number) {
if (find(number) == false)
cout << "Number does not exist in the vector.\n";
else {
int checkpoint = 0;
for (int i = 0; i <= size; i++)
if (ptr[i] == number)
checkpoint = i;
for (int i = checkpoint; i < size; i++)
ptr[i] = ptr[i + 1];
}
ptr[size] = 0;
size--;
}
void orderedVector::findSum(int number) {
for (int i = 0; i <= size; i++) {
for (int j = i+1; j <= size; j++) {
if (ptr[i] + ptr[j] == number) {
cout << "The two numbers that have a sum of " << number
<< " are " << ptr[i] << " and " << ptr[j] << endl;
return;
}
}
}
cout << "No two numbers found that give a sum of " << number << endl;
}
ostream& operator<<(ostream& output, const orderedVector& vector) {
for (int i = 0; i < vector.size; i++)
output << vector.ptr[i] << " ";
output << endl;
return output;
}
istream& operator>>(istream& input, orderedVector& vector) {
int x = 0;
for (int i = 0; i < vector.capacity; i++) {
input >> x;
vector.insert(x);
}
return input;
}
It appears that when I initialize an element, and the array is completely filled, I get this error:
HEAP CORRUPTION DETECTED, CRT detected that the application wrote to memory after end of heap buffer.
I know it's the destructor because when I remove it, no errors occur.
Also, when my vector element is not completely filled (the capacity is bigger than the size), no error occurs.
I would like to know how to fix this, or how the delete operator works in general, and why it causes an error if I fill my dynamically created array.
A dynamic allocation may be deallocated at most once. As such, when you deallocate in a destructor, it is important to establish a class invariant that at most one instance uniquely owns the same pointer. If such invariant is violated, then the destructors of those instances may attempt to delete same pointer twice, which leads to undefined behaviour. Which is bad.
Your class orderedVector indeed deallocates in its destructor. However, the (implicitly generated) copy constructor of the class copies the member variable, which violates the class invariant of unique ownership.
You failed to provide a MCVE, but it is reasonable to guess that your program makes a copy of an instance of orderedVector, leading to undefined behaviour due to multiple delete of the same pointer.
The solution is to either make the class non-copyable and non-movable, or follow the rule of 3 (or 5) i.e. implement the copy (and move) constructors and assignment operators in a way that enforces the invariant of unique ownership.

Code runs when in main() but gives error when in function [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am writing a dynamic matrix class that stores each non-zero value as a List of 3 elements [row,column,value]
I made a dynamic array class called "List", and class"Matrix" a List of list pointers.
My code to transpose the Matrix works:
void transpose(Matrix tripleList)
{
for (int i = 0; i < tripleList.getNumOfElem(); i++)
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
cout << "\n";
}
}
it works when written directly in main() but gives error when in stand alone function. can anyone explains why and how to fix it?
Full code:
#include <iostream>
using namespace std;
class List //a dynamic int pointer array
{
private:
int capacity;
int numOfElem;
int *arr;
//initialize all values in capacity to 0
void initialize(int from)
{
for (int i = from; i < capacity; i++)
{
arr[i] = 0;
}
}
//double the capaicty, then initialize
void expand()
{
capacity *= 2;
int *tempArr = new int[capacity];
for (int i = 0; i < numOfElem; i++)
tempArr[i] = arr[i];
delete[] arr;
arr = tempArr;
initialize(numOfElem);
}
public:
List()//constructor
{
capacity = 10;
numOfElem = 0;
arr = new int[capacity];
}
~List()//destrcutor
{
delete[] arr;
}
//add int to the end of List
void append(int newElement)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = newElement;
}
//Copy all element of an input list to the end of List
void copy(List list)
{
for (int i = 0; i < list.getNumOfElem(); i++)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = list.getAt(i);
}
}
//get reference of the int at an index in te list
int* getAddress(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return &arr[index];
}
//change the value of at specific index
void set(int index, int value)
{
arr[index] = value;
}
//get int at an index in te list
int getAt(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return arr[index];
}
int getNumOfElem()
{
return numOfElem;
}
void displayList()
{
for (int i = 0; i < numOfElem; i++)
{
cout << arr[i] << " ";
}
}
};
class Matrix //a List of list pointers
{
private:
int capacity;
int numOfElem;
List* *arr;
void initialize(int from)
{
for (int i = from; i < capacity; i++)
{
arr[i] = new List;
}
}
void expand()
{
capacity *= 2;
List* *tempArr = new List*[capacity];
for (int i = 0; i < numOfElem; i++)
tempArr[i] = arr[i];
delete[] arr;
arr = tempArr;
initialize(numOfElem);
}
public:
Matrix()
{
capacity = 10;
numOfElem = 0;
arr = new List*[capacity];
}
~Matrix()
{
delete[] arr;
}
void append(List* newElement)
{
if (numOfElem >= capacity)
expand();
arr[numOfElem++] = newElement;
}
void set(int index, List* value)
{
arr[index] = value;
}
List* getAt(int index)
{
if (index < 0 || index >= numOfElem)
throw ("Out of bounds exception!!!");
return arr[index];
}
int getNumOfElem()
{
return numOfElem;
}
};
void transpose(Matrix tripleList)
{
for (int i = 0; i < tripleList.getNumOfElem(); i++)
{
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
cout << "\n";
}
}
int main()
{
int m, n, input;
cout << "Please enter the number of rows and columns of the matrix :\n";
cin >> m >> n;
Matrix tripleListMatrix;
int k = 0;
cout << "Please enter the matrix : \n";
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
cin >> input;
if (input != 0)
{
tripleListMatrix.append(new List);
(*(tripleListMatrix.getAt(k))).append(i + 1);
(*(tripleListMatrix.getAt(k))).append(j + 1);
(*(tripleListMatrix.getAt(k))).append(input);
k++;
}
}
}
cout << "The triple list of matrix is:\n";
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
(*(tripleListMatrix.getAt(i))).displayList();
cout << "\n";
}
cout << "\n\n";
//transpose(tripleListMatrix);
//the code below is the same as in the function transpose but transpose gives error
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
List* list = new List;
(*list).copy(*(tripleListMatrix.getAt(i)));
int temp = (*list).getAt(0);
(*list).set(0, (*list).getAt(1));
(*list).set(1, temp);
(*list).displayList();
//cout << "\t" << list;
cout << "\n";
}
cout << "\n\n";
//checking that tripleListMatrix is unchanged
for (int i = 0; i < tripleListMatrix.getNumOfElem(); i++)
{
(*(tripleListMatrix.getAt(i))).displayList();
cout << "\n";
}
return 0;
}
List* *arr;
When you call transpose(), it makes a copy Matrix because you're not passing by reference. That copy just has a copy of the address for your List, not it's own List object. When the destructor runs on the copy, it clears up the allocated memory, but the original Matrix object in main still points to that same memory. When that object goes away, its destructor tries to free the same memory again and that's bad.
You probably meant:
void transpose(Matrix const & tripleList)
So that no copy is made when calling transpose(), but you should also explicitly delete the copy construtor of Matrix so it cannot be called
Matrix(Matrix const &) = delete;
or make an explicit Matrix copy constructor that makes a deep copy of the memory.

operator overloading [][] 2d array c++

I have a 2D array and I want to define a function that returns the value of the index that the user gives me using operator overloading.
In other words:
void MyMatrix::ReturnValue()
{
int row = 0, col = 0;
cout << "Return Value From the last Matrix" << endl;
cout << "----------------------------------" << endl;
cout << "Please Enter the index: [" << row << "][" << col << "] =" << ((*this).matrix)[row][col] << endl;
}
The operation ((*this).matrix)[row][col] should return an int.
I have no idea how to build the operator [][].
Alternatively, I could concatenate a couple of calls to the operator [], but I didn't succeed in it, because the first call to that operaror will return int* and the second one will return int, and it compel to build another operator, and I dont want to do that.
The data matrix is defined like
int** matrix; matrix = new int*[row];
if (matrix == NULL)
{
cout << "Allocation memory - Failed";
}
for (int i = 0; i < row; i++)//Allocation memory
{
matrix[i] = new int[col];
if (matrix[i] == NULL)
{
cout << "Allocation memory - Failed";
return;
}
}
What can I do?
Thank you,
Simply, such an operator does not exist, so you can not overload it.
A possible solution is to define two classes: the Matrix and the Row.
You can define the operator[] of a Matrix so that it returns a Row, then define the same operator for the Row so that it returns an actual value (int or whatever you want, your Matrix could be also a template).
This way, the statement myMatrix[row][col] will be legal and meaningful.
The same can be done in order to assign a new Row to a Matrix or to change a value in a Row.
* EDIT *
As suggested in the comments, also you should take in consideration to use operator() instead of operator[] for such a case.
This way, there wouldn't be anymore the need for a Row class too.
You can define your own operator [] for the class. A straightforward approach can look the following way
#include <iostream>
#include <iomanip>
struct A
{
enum { Rows = 3, Cols = 4 };
int matrix[Rows][Cols];
int ( & operator []( size_t i ) )[Cols]
{
return matrix[i];
}
};
int main()
{
A a;
for ( size_t i = 0; i < a.Rows; i++ )
{
for ( size_t j = 0; j < a.Cols; j++ ) a[i][j] = a.Cols * i + j;
}
for ( size_t i = 0; i < a.Rows; i++ )
{
for ( size_t j = 0; j < a.Cols; j++ ) std::cout << std::setw( 2 ) << a[i][j] << ' ';
std::cout << std::endl;
}
}
The program output is
0 1 2 3
4 5 6 7
8 9 10 11
I have no idea how to build the operator [][].
Sometimes it is fine to use a different operator, namely ():
int& Matrix::operator () (int x, int y)
{
return matrix[x][y];
}
const int& Matrix::operator () (int x, int y) const
{
return matrix[x][y];
}
int diagonal (const Matrix& m, int x)
{
return m (x, x); // Usage.
}
Advantage:
No need to use "intermediate" class like Row or Column.
Better control than with Row& Matrix operator (int); where someone could use the Row reference to drop in a row of, say, illegal length. If Matrix should represent a rectangular thing (image, matrix in Algebra) that's a potential source of error.
Might be less tedious in higher dimensions, because operator[] needs classes for all lower dimensions.
Disadvantage:
Uncommon, different syntax.
No more easy replacement of complete rows / columns, if that's desired. However, replacing columns is not easy, anyway, provided you used rows to model (and vice versa).
In either case, there are pros and cons if the number of dimensions are not known at runtime.
I was looking for self-tested array replacement...
Improved version returns reference or NULL reference and checks boundaries inside.
#include <iostream>
#include <iomanip>
template<typename T, int cols>
class Arr1
{
public:
Arr1(T (&place)[cols]) : me(place) {};
const size_t &Cols = cols;
T &operator [](size_t i)
{
if (i < cols && this != NULL) return me[i];
else {
printf("Out of bounds !\n");
T *crash = NULL;
return *crash;
}
}
private:
T (&me)[cols];
};
template<typename T, int rows, int cols>
class Arr2
{
public:
const size_t &Rows = rows;
const size_t &Cols = cols;
Arr2() {
ret = NULL;
for (size_t i = 0; i < rows; i++) // demo - fill member array
{
for (size_t j = 0; j < cols; j++) matrix[i][j] = cols * i + j;
}
}
~Arr2() {
if (ret) delete ret;
}
Arr1<T, cols>(&operator [](size_t i))
{
if (ret != NULL) delete ret;
if (i < rows) {
ret = new Arr1<T, cols>(matrix[i]);
return *ret;
}
else {
ret = NULL;
printf("Out of bounds !\n");
return *ret;
}
}
//T(&MemberCheck)[rows][cols] = matrix;
private:
T matrix[rows][cols];
Arr1<T, cols> *ret;
};
template<typename T,int rows, int cols>
class Arr
{
public:
const size_t &Rows = rows;
const size_t &Cols = cols;
T(&operator [](size_t i))[cols]
{
if (i < rows) return matrix[i];
else {
printf("Out of bounds !\n");
T(*crash)[cols] = NULL;
return *crash;
}
}
T (&MemberCheck)[rows][cols] = matrix;
private:
T matrix[rows][cols];
};
void main2()
{
std::cout << "Single object version:" << endl;
Arr<int, 3, 4> a;
for (size_t i = 0; i <= a.Rows; i++)
{
int *x = &a[i][0];
if (!x) printf("Fill loop - %i out of bounds...\n", i);
else for (size_t j = 0; j < a.Cols; j++) a[i][j] = a.Cols * i + j;
}
for (size_t i = 0; i < a.Rows; i++)
{
for (size_t j = 0; j <= a.Cols; j++) {
std::cout << std::setw(2) << a[i][j] << ' ';
if (a.MemberCheck[i][j] != a[i][j])
printf("Internal error !");
}
std::cout << std::endl;
}
std::cout << endl << "Double object version:" << endl;
Arr2<int, 3, 4> a2;
for (size_t i = 0; i < a2.Rows; i++)
{
for (size_t j = 0; j <= a2.Cols; j++) {
int &x = a2[i][j];
if (&x)
{
x++;
std::cout << std::setw(2) << a2[i][j] << ' ';
//if (&a2.MemberCheck[i][j] != &a2[i][j])
// printf("Internal error !");
}
}
}
}
Output
Single object version:
Out of bounds !
Fill loop - 3 out of bounds...
0 1 2 3 4
4 5 6 7 8
8 9 10 11 -858993460
Double object version:
1 2 3 4 Out of bounds !
5 6 7 8 Out of bounds !
9 10 11 12 Out of bounds !
it works fine in the program below
#include<iostream>
using namespace std;
class A{
public:
int r,c;
int** val;
A()
{
r=0;c=0;val=NULL;
}
A(int row,int col)
{
r=row;c=col;
int count=0;
val=new int*[row];
for(int i=0;i<r;i++){
val[i]=new int[col];
for(int j=0;j<c;j++){
count++;
val[i][j]=count;
}
}
}
int* &operator[](int index){
return val[index];
}
};
int main(void){
A a(3,3);
cout<<a[1][2];
return 0;
}
here, a[1][2] first computes a[1]-->which returns 2nd row as (int*) type
then it's read as (int*)[2] which returns 3rd element of that row.In short,
a[1][2]------>(a[1])[2]------>(val[1])[2]------>val[1][2].

C++ HEAP error when delete [] is called

I keep getting the error in VS 2100 "CRT detected that the application wrote to memory before start of heap buffer"
Can anyone help? My int Main is all the way on the bottom. The error occur when the delete [] command is run on the operator= function
#include "intset.h"
const int MAXINITIALSIZE = 5;
int IntSet::numOfArray = 0;
IntSet::IntSet(int a, int b, int c, int d, int e)
{
numOfArray++;
int tempArray[] = {a, b, c, d, e};
size = determineHighest(tempArray) + 1; //determines largest int
cout << "size is " << size << endl;
arrayPtr = new bool[size]; //creates array of bool
for (int i = 0; i < size; i++) //fill bool array
{
arrayPtr[i]= false; //arrayptr is a bool pointer created in the header
}
for (int i = 0; i < MAXINITIALSIZE; i++)
{
arrayPtr[tempArray[i]]= true;
}
for (int i = 0; i < size; i++)
{
cout << &arrayPtr[i] << endl;
}
}
IntSet::IntSet(const IntSet &intsetObject)
{
numOfArray++;
size = intsetObject.size;
arrayPtr = new bool[size];
for (int i = 0; i < size; i++)
{
if (intsetObject.arrayPtr[i])
arrayPtr[i] = intsetObject.arrayPtr[i];
}
}
IntSet::~IntSet()
{
--numOfArray;
delete [] arrayPtr;
arrayPtr = NULL;
}
int IntSet::determineHighest(int tempArray[])
{
int temp = tempArray[0];
for (int i = 1; i < MAXINITIALSIZE; i++)
{
if (tempArray[i] > temp)
temp = tempArray[i];
else
continue;
}
return temp;
}
IntSet& IntSet::operator=(const IntSet &intsetObject) //ask about IntSet&
{
cout << "inside operator=" << endl;
if (&intsetObject != this)
{
for (int i = 0; i < size; i++)
{
cout << &arrayPtr[i] << endl;
}
delete [] arrayPtr; //HEAP ERROR HERE!
for (int i = 0; i < size; i++)
{
cout << &arrayPtr[i] << endl;
}
size = intsetObject.size
arrayPtr = new bool[size]();
for (int i = 0; i < size; i++)
{
if (intsetObject.arrayPtr[i])
arrayPtr[i] = intsetObject.arrayPtr[i];
}
}
return *this;
}
ostream& operator<<(ostream &output, const IntSet &intsetObject)
{
output << "{ ";
for (int i = 0; i < intsetObject.size; i++)
{
if (intsetObject.arrayPtr[i] == true)
{
output << i << " ";
}
else
continue;
}
output << "}";
return output;
}
//main
#include "intset.h"
int main() {
IntSet object2(9);
IntSet object4(3,6);
object4 = object2;
return 0;
}
This can only happen if arrayPtr is accessed with a negative index. I suspect your defaults for a,b,c,d,e are -1 in the declaration for IntSet::IntSet, so it is writing to arrayPtr[-1] in the set-true loop. Check for tempArray[i] >= 0 there.
Also, you can't print the array after you have deleted it, so you should remove those lines after the delete, although they should be "harmless" in that only garbage will be printed, but who knows - the OS could release the page containing the array and it could segfault your program.
Finally, you should not test if (intsetObject.arrayPtr[i]) in the copy & = operators. Otherwise all "false" elements in the source array become uninitialized in the destination array (new bool[size] does not initialize the array to all false).