Class Variable Declaration

Hi ALL,

I am in my first C++ this semester and am having some issues with a MyVector class I created earlier on in the class. I made variables global for the object which is a "NO NO" as my teacher said for object oriented programming. I believed I have declared the variables correctly now, but ever since I am receiving an

"Invalid allocation size: 4294967295 bytes." When calling my push_back function.

Below is my code (driver.cpp, MyVector.h, and MyVector.cpp), I understand that using "using namespace std;" is not best practice but this is how my teacher wants it.... I don't know why.

I have stepped through my code and can't identify what I need to do next. I have a feeling it is how I had the variable declared before. They were previously in the MyVector.cpp declared globally as follows before the change.

1
2
3
4
5
6
//Declarations
int vSize;
int* myArray;
int startCap = 2;
const int TWO = 2;
const int ZERO = 0;


Any help or a point in the right direction would be appreciated.

Thanks in advance!

driver.cpp
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
#include <iostream>
#include "MyVector.h"     
using namespace std;

// the printV function
// used to test the copy constructor
// parameter: a MyVector object
void printV(MyVector);

int main( )
{
	cout << "\nCreating a vector Sam of size 4.";
	MyVector sam( 4 );

	cout << "\nPush 12 values into the vector.";
	for (int i = 0; i < 12; i++)
		sam.push_back(i);

	cout << "\nHere is sam: ";
	cout << sam;
	cout << "\n---------------\n";

		cout << "\nCreating a vector Joe of size 4.";
	MyVector joe( 4 );
	cout << "\nPush 6 values into the vector.";
	for (int i = 0; i < 6; i++)
		joe.push_back(i * 3);

	cout << "\nHere is joe: ";
	cout << joe;
	cout << "\n---------------\n";
	
	cout << "\nTest the overloaded assignment operator \"joe = sam\": ";
	joe = sam;

	cout << "\nHere is sam: ";
	cout << sam;
	cout << "\n---------------\n";

	cout << "\nHere is joe: ";
	cout << joe;
	cout << "\n---------------\n";

	// pass a copy of sam by value
	printV(sam);
	

	cout << endl;
	system("PAUSE");
	return 0;
}

void printV(MyVector v)
{
	cout << "\n--------------------\n";
	cout << "Printing a copy of a vector\n";
	cout << v;
}


MyVector.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
#include <fstream>
using namespace std;

class MyVector
{
	public:

		int vSize;
		int* myArray;
		int startCap;

		//Constructor
		MyVector ();
		MyVector (int n);

		//Deconstructor
		~MyVector ();
		
		//Copy Constructor
		MyVector(const MyVector&);

		//Overloaded Assignment Operator
		MyVector& operator=(const MyVector&);

		//Getter Function: size
		//Purpose: Return the size of the vector
		//Return Type: int
		//Parameters: NONE
		int size () const;

		//Getter Funcation: capacity
		//Purpose: Return the capacity of the vector
		//Return Type: int
		//Parameters: NONE
		int capacity () const;

		//Setter Funcation: clear
		//Purpose: Clears the contents of the vector and sets the siz to zero and the capacity to two 
		//Return Type: void
		//Parameters: NONE
		void clear ();

		//Setter Funcation: push_back
		//Purpose: Adds integer to vector. If vector is not big enough double the vectors current capacity
		//Return Type: void
		//Parameters: int n
		void push_back (int n);

		//Getter Function: at
		//Purpose: Return value of emement at position n
		//Return Type: Int
		//Parameters: int n
		int at (int n) const;

		// overloaded << operator - a nonmember
		// make it a friend so it can see the array
		friend ostream& operator<<(ostream& out, const MyVector& s);
};



MyVector.cpp
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include "MyVector.h"
#include <iostream>
#include <array>
using namespace std;

//default constructors
MyVector::MyVector()
{
	int startCap = 2;
	int vSize = 0;
	myArray = new int[startCap];
}

MyVector::MyVector(int n)
{
	int startCap = n;
	int vSize = 0;
	myArray = new int[startCap];
}

//Deconstructor
MyVector::~MyVector()
{
	//deleting myArray and clearing it
	if (myArray != NULL)
	{
		delete [] myArray;
		myArray = NULL;
	}
}

// Copy constructor
// Purpose: Copy the data into this Array
// Parameters: a MyVector object
// Returns: none
MyVector::MyVector( const MyVector& v)
{
	// Be sure that the string is not null
	if ( v.myArray != NULL )
	{
		// allocate storage and copy char array
		startCap = v.startCap;	   
		//theStr = new char[strlen(b.theStr) + 1];
		myArray = new int[startCap];
		//strncpy(theStr, b.theStr, theStrLen );
		for (int i = 0; i < startCap; i++)
			myArray[i] = v.myArray[i];
	}
	else  // nothing to copy
	{
		myArray = NULL;
		startCap = 0;
	}
}

// The overloaded assignment operator
MyVector& MyVector::operator= (const MyVector& v)
{
	// test for self-copy
	if (this == &v)
	   return *this;

	// Consider two cases.
	if (startCap >= v.startCap)  // there is room
	{
		if (v.myArray != NULL)
		{
			for (int i = 0; i < startCap; i++)
			{
				this->myArray[i] = v.myArray[i];
			}
		}
		else // copying a null string
		   myArray = NULL;

		startCap = v.startCap;
		return *this;
	}
	else  // not enough room
	{
		// delete the original array
		delete [] myArray;

		startCap = v.startCap;
		if (startCap > 0) // okay, something to copy
		{
		   // allocate the storage and copy
			myArray = new int[startCap + 1];
			for (int i = 0; i < vSize; i++)
			{
				this->myArray[i] = v.myArray[i];
			}
		}
	   else // nothing to copy
	      myArray = NULL;

	   return *this;
   }
}

//Getter Function: size
//Purpose: Return the size of the vector
//Return Type: int
//Parameters: NONE
int MyVector::size() const
{
	return vSize;
}

//Getter Funcation: capacity
//Purpose: Return the capacity of the vector
//Return Type: int
//Parameters: NONE
int MyVector::capacity() const
{
	return startCap;
}

//Setter Funcation: clear
//Purpose: Clears the contents of the vector and sets the siz to zero and the capacity to two 
//Return Type: void
//Parameters: NONE
void MyVector::clear() 
{
	//clearing the array and setting the array to the default cap of 2 and size of 0
	if (myArray != NULL)
	{
		delete [] myArray;
		myArray = NULL;
	}
	
	vSize = 0;
	startCap = 2;
	int* myArray = new int[startCap];
}

//Setter Funcation: push_back
//Purpose: Adds integer to vector. If vector is not big enough double the vectors current capacity
//Return Type: void
//Parameters: int n
void MyVector::push_back(int n)
{
	

	//verifying the we are not writting the value
	//past the capacity of the array
	if(vSize + 1 > startCap)
	{
		//Doubling the array size
		startCap = vSize * 2;
		//creating a temp array
		int* temp = new int[startCap];

		//for loop copying the contents of myArray to temp
		for (int i = 0; i < vSize; i++)
		{
			temp[i] = myArray [i];
		}
		
		//deleting the myArray
		delete[] myArray;
		//copying myArray from temp
		myArray = temp;
	}

	//finding the end of the array and incrementing and adding one to the array
	myArray[vSize] = n;
	vSize++;
}

//Getter Function: at
//Purpose: Return value of emement at position n
//Return Type: Int
//Parameters: int n
int MyVector::at(int n) const
{
	//If statment that returns value of the point in the array
	//or throws an error telling the user the index at which it failed
	if(n < vSize)
		return myArray[n];
	throw n;
}

ostream& operator<<(ostream& out, const MyVector& s)
{
	for (int i = 0; i < s.vSize; i++)
		out << s.myArray[i] << ' ';
	return out;
}
Last edited on
http://www.cplusplus.com/doc/tutorial/variables/ (scope)
1
2
3
4
5
6
7
MyVector::MyVector()
{
	int startCap = 2; //local variable
	int vSize = 0;
	myArray = new int[startCap];
} //local variable dies
//members remain uninitialized 
Thanks.

Just found that I that was the case in the first two Constructors and the Clear ().

Another question, do you see anything wrong with my the following code?
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
MyVector& MyVector::operator= (const MyVector& v)
{
	// test for self-copy
	if (this == &v)
	   return *this;

	// Consider two cases.
	if (startCap >= v.startCap)  // there is room
	{
		if (v.myArray != NULL)
		{
			for (int i = 0; i < vSize; i++)
			{
				this->myArray[i] = v.myArray[i];
			}
		}
		else // copying a null string
		   myArray = NULL;

		startCap = v.startCap;
		return *this;
	}
	else  // not enough room
	{
		// delete the original array
		delete [] myArray;
		myArray = NULL;
		startCap = v.startCap;
		if (startCap > 0) // okay, something to copy
		{
		   // allocate the storage and copy
			myArray = new int[startCap];
			for (int i = 0; i < vSize; i++)
			{
				this->myArray[i] = v.myArray[i];
			}
		}
	   else // nothing to copy
	      myArray = NULL;

	   return *this;
   }
}


When I try to copy two objects I only get part some of the values.

The call is like so...

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
#include <iostream>
#include "MyVector.h"     
using namespace std;

// the printV function
// used to test the copy constructor
// parameter: a MyVector object
void printV(MyVector);

int main( )
{
	cout << "\nCreating a vector Sam of size 4.";
	MyVector sam( 4 );

	cout << "\nPush 12 values into the vector.";
	for (int i = 0; i < 12; i++)
		sam.push_back(i);

	cout << "\nHere is sam: ";
	cout << sam;
	cout << "\n---------------\n";

		cout << "\nCreating a vector Joe of size 4.";
	MyVector joe( 4 );
	cout << "\nPush 6 values into the vector.";
	for (int i = 0; i < 6; i++)
		joe.push_back(i * 3);

	cout << "\nHere is joe: ";
	cout << joe;
	cout << "\n---------------\n";
	
	cout << "\nTest the overloaded assignment operator \"joe = sam\": ";
	joe = sam;

	cout << "\nHere is sam: ";
	cout << sam;
	cout << "\n---------------\n";

	cout << "\nHere is joe: ";
	cout << joe;
	cout << "\n---------------\n";

	// pass a copy of sam by value
	printV(sam);
	

	cout << endl;
	system("PAUSE");
	return 0;
}

void printV(MyVector v)
{
	cout << "\n--------------------\n";
	cout << "Printing a copy of a vector\n";
	cout << v;
}
Another question, do you see anything wrong with my the following code?


Why is startCap a member of the class? How does it differ from vSize? Why isn't vSize updated for the target object in operator= or accessed for the source object in operator=? Why would you ever set myArray to NULL without freeing the memory first?
Great questions, which inevitably led me to my answer...

The startCap and vSize are used for the number of actual object in the array and for the capacity of the array. Updated the vSize for the target object updated the number of object in the array which allowed the whole array to be copied over.

The final question's answer is simply I don't know. Looking at example code I threw this together. I have now removed the NULL seeing that this was incorrect.

It looks as though the MyVector& MyVector::operator= (const MyVector& v) is working as it should.

I am now sure why but when I call the printV(sam); it will rattle off the array that was copied but continue until the program crashes. Like so...

-----------------
Printing a copy of a vector
0 1 2 3 4 5 6 7 8 9 10 11 -842150451 -842150451 -842150451 -842150451 -33686019 -1414812757 ...... 


Is this because of the following code?

1
2
3
4
5
6
ostream& operator<<(ostream& out, const MyVector& s)
{
	for (int i = 0; i < s.vSize; i++)
		out << s.myArray[i] << ' ';
	return out;
}
Not having seen your updated code, I can only assume that you are still failing to update vSize at some point. Note that in the code you posted above it is not set properly in the copy constructor or operator=.

Having taken a closer look at the class code, I see why startCap is a member of the class. What I don't see is why it is named startCap instead of capacity, since it does not remain the starting capacity but reflects the actual capacity of the array. My question was motivated by the inaccurate name.
Thanks for all the help and sorry for the confusion!
Topic archived. No new replies allowed.