I am at a loss as to why this doesn't work

Yes, this is an assignment for school. I have been working on this for a couple weeks now and I have spent time looking at this forum and other resources and can't figure out what I am doing wrong. Please look at my code. It is probably something that I just can't see because I have looked at it too much.
I am including a bunch of extra, just so you can see that I have actually put the effort in on this and I have more to do but I need to get past the current two hangups.
The overload of + and << don't work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// DynamicArray.h
#ifndef DYNAMICARRAY_H
#define DYNAMICARRAY_H
class DynamicArray {
private:
	int *p_ToArray;
	int length;
	int nextIndex;
	void bumpArray();
public:
	DynamicArray();
	~DynamicArray();
	void add(int numToAdd);
	void remove(int index);
	void print();
	int get(int index);
	int sum();
	int size();
	int& operator[](int index); 
	void operator =(const DynamicArray& da);
	DynamicArray operator+(DynamicArray &);
	friend ostream& operator <<(ostream& outs, const DynamicArray& da);
};
#endif // DYNAMICARRAY_H 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include "DynamicArray.h"
#include <iostream>
#include <string>
using namespace std;
// Default constructor to create dynamic array with initial size of 10
DynamicArray::DynamicArray()
{
	length = 10;
	p_ToArray = new int[length];
	for (int i = 0; i < 10; i++)
		p_ToArray[i] = 0;
	nextIndex = 0;
}

DynamicArray::~DynamicArray() // The destructor
{
	delete[] p_ToArray;
}

void DynamicArray::bumpArray()
{
	int *p_NewArray;
	length += 10;
	p_NewArray = new int[length];
	for (int i = 0; i < nextIndex; i++)
		p_NewArray[i] = p_ToArray[i];
	for (int j = nextIndex; j < length; j++)
		p_NewArray[j] = 0;
	delete[] p_ToArray;
	p_ToArray = p_NewArray;
}

void DynamicArray::add(int numToAdd)
{
	if (nextIndex == length)
	{
		bumpArray();
	}
	p_ToArray[nextIndex] = numToAdd;
	nextIndex++;
}

void DynamicArray::remove(int index)
{
	for (int i = index; i < nextIndex; i++)
		p_ToArray[i] = p_ToArray[i + 1];
	nextIndex--;
	p_ToArray[nextIndex] = 0;
}

void DynamicArray::print() //prints item of the array comma separated. 
{
	for (int i = 0; i < nextIndex; i++)
	{
		cout << p_ToArray[i];
		if (i == nextIndex - 1)
		{
			cout << endl; // if last element, just a new line
		}
		else
		{
			if ((i + 1) % 20 == 0)
				cout << "," << endl;	// new line after 20 elements
			else
				cout << ", ";	//  comma after every element
		}
	}
}

int DynamicArray::get(int index)
{
	return p_ToArray[index];
}

int DynamicArray::sum()
{
	int sum = 0;
	for (int i = 0; i < nextIndex; i++)
		sum += p_ToArray[i];
	return sum;
}

int DynamicArray::size()
{
	return length;
}

int& DynamicArray::operator[](int index)
{
	if (index >= length)
	{
		bumpArray();
	}
	return *(p_ToArray + index);
}

// Overloading assignment (=) operator
// Assigns a value to a DynamicArray object using the '=' operator.
void DynamicArray::operator =(const DynamicArray& da)
{
	int size = da.length;
	nextIndex = da.nextIndex;
	if (size > length) // checks if the default size is big enough
					   //  or is the array being copied smaller?
	{					//  if the default array is too small
		delete[] p_ToArray;		// destroy the default array
		length = size;		//  set the new array to create equal in size
		p_ToArray = new int[length];  // create an array of size length
	}
	for (int i = 0; i < size; i++)		// copy all the elements
		p_ToArray[i] = da.p_ToArray[i];   // this appears to work, I think...
	// at least to assign an array to the values of another array
}

// Need to make these .. required

DynamicArray DynamicArray::operator+(DynamicArray& oDAo)  // Operator overloading, I hope
{
	DynamicArray temp;  //  creates a new object 
	int t = 0;
	for (int i = 0; i < nextIndex; i++) 		// copy old array to new array 
	{
		t = p_ToArray[i];
		temp.add(t);
	}

	for (int j = 0; j < oDAo.size(); j++) // copy added array
	{
	t = oDAo[j];
	temp.add(t);
	}
	temp.print();  //  only added this for troubleshooting
	//  works fine inside the instance but ...
//  when I try to return the temp object it crashes the compiler.
	return temp; // a reference to the element
};

//  I built this just like the teacher described and it doesn't work
//  It won't even compile on either my Linux or Windows system
// Overload the << operator to print the elements
ostream& operator<<(ostream& outs, const DynamicArray& da)
{
	//  almost the same code from .print, in code above...
	for (int i = 0; i < da.nextIndex; i++)
	{
		outs << da.p_ToArray[i];
		if (i == da.nextIndex - 1)
		{
			outs << endl; // if last element, just a new line
		}
		else
		{
			if ((i + 1) % 20 == 0)
				outs << "," << endl;	// new line after 20 elements
			else
				outs << ", ";	//  comma after every element
		}
	}
	return outs;
}



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//  main.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

#include "DynamicArray.h"

using namespace std;

//					prototype local functions
//  this works, but I deleted it because my submission was too long.
void toContinue();		//		used to hold data on screen until enter key
// let me know if you want the files.
bool testOpenFile(ifstream& dSource, string); // checks if file exists and opens it

//					begin main function
int main(int argc, char* argv[])
{
	// default file names so I don't have to type it every time.
	string inFILE_a = "C:\\Users\\Chris\\Desktop\\C++\\Program 5\\data5i.dat";
	string inFILE_b = "C:\\Users\\Chris\\Desktop\\C++\\Program 5\\data5j.dat";

	ifstream dSa;		//	name the file stream variable
	ifstream dSb;		//	name the file stream variable
						// receives file names if they are entered at the command line.
	if (argc > 1)
	{
		inFILE_a = argv[1];
		inFILE_b = argv[2];
	}

	//	test if file exists and open it for reading
	if (!(testOpenFile(dSa, inFILE_a) && testOpenFile(dSb, inFILE_b)))
	{
		return 1;   //  data source failed, exit main, program stop.
	}
	else
	{
		DynamicArray da1; // create a dynamic array object, initial size is 10
		DynamicArray da2; // create a dynamic array object, initial size is 10

//  Do some work in here to load data into the dynamic arrays, well tested, works.

		DynamicArray da3; // create another empty array 
		da3 = da1;  //  This appears to work
		//  change a few values
		da1[3] = 14; // use works just like a regular array
		da2[3] = 16; // use works just like a regular array
		da3[3] = 24; // use works just like a regular array
		da3.remove(5);  //  works like it is supposed to.

		cout << "\nThe elements in array 1 are: " << endl;
		//  I need to overload << to work here but made this .print as a workaround
		da1.print();  //  this works but doesn't fill the requirement
		cout << "\nThe sum of all elements in array 1 is ";
		cout << da1.sum() << endl;	//  works, returns the sum and that prints.
		cout << "\nThe current size of array 1 is ";
		cout << da1.size() << endl;	//  works, returns the size and that prints.

		// only did these to validate that there are three separate sets of data
		cout << "\nThe elements in array 2 are: " << endl;
		da2.print();
		cout << "\nThe sum of all elements in array 2 is " << da2.sum() << endl;
		cout << "\nThe current size of array 2 is " << da2.size() << endl;
		cout << "\nThe elements in array 3 are: " << endl;
		da3.print();
		cout << "\nThe sum of all elements in array 3 is " << da3.sum() << endl;
		cout << "\nThe current size of array 3 is " << da3.size() << endl;
		
		//  this crashes the compiler -  
		da3 = da1 + da2;  //  I want da3 to be all the elements in da1 and da2 no math.
		
	}

//	open the input file, write an error if it fails 
bool testOpenFile(ifstream& dSource, string fileName)
{
	dSource.open(fileName.c_str());	//  allows define of file name at start of code
	if (dSource.fail())
	{
		cout << "Couldn't open input file.  File not found." << endl;
		toContinue();
		return false;	//  Exit with an error if the input file does not exist.
	}
	return true;
}
Last edited on
I have tested the program with the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main(int argc, char* argv[])
{
  DynamicArray numbers;

  for (int i = 0; i < 10; i++)
  {
    numbers.add(i);
  }

  cout << "Values of numbers: "; 
  numbers.print();

  DynamicArray numbers2 = numbers;

  cout << "Values of numbers2: "; 
  numbers2.print();

  system("pause");
}


At the end it crashes. I guess the problem lies in the destructor.
Both times p_ToArray points to the same address and then of course it crashes in the destructor of numbers2.

I hope this helps.
In the programming class, we have taken this same code and expanded it by adding more functionality and this is the third iteration using the same base code.
The object, and creation / destruction of the memory don't appear to be the problem. I have stepped through the code using Visual Studio 2015 and the point at which the crash occurs is when the data (result of adding the two dynamic arrays together) is passed back to main.
I keep thinking that I am handling it wrong, but the only hint that the instructor would give is that the data is being destroyed before it is passed back. That doesn't help me understand why or how to fix it.
The problem is that you have copy operator, but no copy constructor. This is required when you return the temp object on line 135. Without the copy contructor you have shallow copy, i.e. you have pointer from the temporary object which are already deleted.

Something like this:
1
2
3
4
5
6
...
	DynamicArray(const DynamicArray& da)
{
	operator =(da);
}
...
I really appreciate the help, but I am not sure what to do with it.
I am not sure how this works.
I understand that you don't want to do my work for me and that is not what I am asking for, I just need to understand how it works so that I can implement this.
Also, I am not done writing this program yet, I have three more overloads that I have to make work besides these. I need to understand it if you can give me some help.
Also, why is the compiler telling me that the 'ostream' is ambiguous in my overload of the stream insertion << ?? I did that exactly like the example the instructor gave and it won't even compile.
Read http://en.cppreference.com/w/cpp/language/rule_of_three


> why is the compiler telling me that the 'ostream' is ambiguous in my overload
> of the stream insertion << ?
If you have a compiler error, then post it verbatim.
Don't paraphrase it as you may leave out important information, especially if you don't understand the error.

Also, I would apreciate if you upload your code to github or similar, so I don't have create the files manually (which I won't).


Your header should be self-contained.
DynamicArray.h makes a reference to ostream, so it should include the relevant header #include <iostream> (perhaps a forward declaration would work)
Also, the correct name is `std::ostream'
Last edited on
Thank you very much for the reference material link. I was able to use it to fix one part of my problem. The addition operator and the equality operator are now working in concert and I can add one array to another the way it was intended.
This is a weight off my mind.

You also nailed it with regard to the #include <iostream> .
I realize that I should have had it in my .h file instead of in my DynamicArray.cpp

As it is now, the program is working. I really appreciate the pointers!

I still have three more overloads to create but now that I have a better understanding to work with, I think that the math will be the hard part on those.

Here is what I have remaining to implement if anyone wants to offer any suggestions:


overload the following operators

	(-) - Intersection : The intersection of A and B, is the set
		of all things that are members of both A and B.
	(\) - Complement : The relative complement of B in A, is the
		set of all elements that are members of A but not members of B
	(*) - Cartesian product : The Cartesian product of two sets
		A and B, denoted by A × B is the set of all ordered pairs
		(a, b) such that a is a member of A and b is a member of B.

Last edited on
Topic archived. No new replies allowed.