Vector subscript overflow issue while retaining vector elements

Any time program runs through line 42, 43, 44 i get vector subscript over flow error,it throws exception invalid parameter passed in function. I was trying to retain elements stored in vector from function and pass those elements to different function to compare values. Can vector be used as array to retain values once it is returned from function?


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
cout << "girls name returned from function before entering function " << girlsNames[0] << endl

// Name Search.cpp : Defines the entry point for the console application.
//

//#include "stdafx.h"
#include<iostream>
#include<iomanip>
#include<fstream>
#include<vector>
#include<string>
using namespace std;
string getGirlName(string);
string getBoyName(string);
int girls(vector<string>);
int boys(vector<string>);
int girlCompare(vector<string>, string, int);
int boyCompare(vector<string>, string, int);



int main()
{
	vector<string>girlsNames;
	vector<string>boysNames;

	string girlName, gName;
	string boyName, bName;
	int gnum, bnum;
	gName = getGirlName(girlName);
	cout << "Girls name from user input is :" << gName << endl;
	system("pause");
	bName = getBoyName(boyName);
	cout << "Boyss name from user input is :" << bName << endl;
	system("pause");
	gnum = girls(girlsNames);
	cout << "total girls names listed is " << gnum << endl;
	system("pause");
	bnum = boys(boysNames);
	cout << "total name of boys listed is " << bnum << endl;
	system("pause");
	cout << "girls name returned from function before entering function " << girlsNames[0] << endl;
	girlCompare(girlsNames, gName, gnum);
	boyCompare(boysNames, bName, bnum);

	system("pause");

	return 0;
}

string getGirlName(string name)
{
	string girlName;
	cout << "Enter name of girl: ";
	getline(cin, girlName);
	return girlName;
}

string getBoyName(string name)
{
	string boyName;
	cout << "Enter name of boy: ";
	getline(cin, boyName);
	return boyName;
}

int girls(vector<string>girlsNames)
{
	string girl;
	ifstream girlsArray;
	girlsArray.open("C:\\Users\\Visual Studio 2017\\Projects\\girlsNames.txt");
	if (!girlsArray)
	{
		cout << "File did not open" << endl;
	}


	while (!girlsArray.eof())
	{
		girlsArray >> girl;
		girlsNames.push_back(girl);
	}
	girlsArray.close();
	int gnum = girlsNames.size();
	
	for (int i = 0; i < (gnum - 1); i++)
	{
		//cout << girlsNames[i] << endl;
	}
	return gnum;
}

int boys(vector<string>boysNames)
{
	cout << endl;
	string boy;
	ifstream boysArray;
	boysArray.open("C:\\Users\\Visual Studio2017\\Projects\\boysNames.txt");
	if (!boysArray)
	{
		cout << "File did not open" << endl;
	}


	while (!boysArray.eof())
	{
		boysArray >> boy;
		boysNames.push_back(boy);
	}
	boysArray.close();
	int num = boysNames.size();
	
	for (int i = 0; i < (num - 1); i++)
	{
		//cout << boysNames[i] << endl;
	}
	return num;
}

int girlCompare(vector<string>girlsNames, string gName, int gnum)
{
	cout << "gnum passed to function: " << gnum << endl;
	system("pause");
	cout << "girl name input by user passed to function: " << gName << endl;
	system("pause");

	for (int i = 0; i < gnum-1 ; ++i)
	{
		system("pause");
		if (gName == girlsNames[i])
		{
			system("pause");
			cout << girlsNames[i] << " is available in list" << endl;
		}
		else
		{
			cout << girlsNames[i] << " is not availalbe in list" << endl;
		}
	}
	return gnum;
}

int boyCompare(vector<string>boysNames, string bName, int bnum)
{
	for (int i = 0; i < bnum-1 ; ++i)
	{
		if (bName == boysNames[i])
		{
			cout << boysNames[i] << " is available in list" << endl;
		}
		else
		{
			cout << boysNames[i] << " is not availalbe in list" << endl;
		}
	}
	return bnum;
}
Last edited on
Any time program runs through line 42, 43, 44 i get vector subscript over flow error

You haven't pushed anything onto the girslsName vector. So a reference to girlsNames[0] in invalid. See comment regarding lines 67 & 93.

Problems:
Line 1: What is this?

Line 51,59: Why are you passing name as an argument. You don't use it.

Line 67,93: You're passing the vector by value, which means the function is operating on a copy. The caller's vector is not modified. Pass the vector by reference if you want to modify the caller's vector.

Line 78,105: Do not loop on (! stream.eof()) or (stream.good()). This does not work the way you expect. The eof bit is set true only after you make a read attempt on the file. This means after you read the last record of the file, eof is still false. Your attempt to read past the last record sets eof, but you're not checking it there. You proceed as if you had read a good record. This will result in reading an extra (bad) record. The correct way to deal with this is to put the >> (or getline) operation as the condition in the while statement.
1
2
3
  while (stream >> var) // or while (getline(stream,var))
  {  //  Good operation
  }


Line 86,113,145: You shouldn't be subtracting 1 from gnum/num/bnum. I suspect you're doing this because you're you got an extra record due to looping on eof().

Line 74,101: If the open fails, you output a message (good), then proceed as if nothing was wrong (bad).
Last edited on
Hi Thank you for highlighting errors and weak points,

Problems:
Line 1: What is this?
-This is error on copy paste of program from source code.

Line 51,59: Why are you passing name as an argument. You don't use it.
-yes i should have left () , no need to pass argument as i am passing any thing . will improve this in future coding.

Line 67,93: You're passing the vector by value, which means the function is operating on a copy. The caller's vector is not modified. Pass the vector by reference if you want to modify the caller's vector.
- i though vector can work just like array, in array i believe we don't have to define as reference it can hold and pass modified value out of function without use of &. I gave a shot thinking same as array and vector would function same way. I will pass is as reference .

Line 78,105: Do not loop on (! stream.eof()) or (stream.good()). This does not work the way you expect. The eof bit is set true only after you make a read attempt on the file. This means after you read the last record of the file, eof is still false. Your attempt to read past the last record sets eof, but you're not checking it there. You proceed as if you had read a good record. This will result in reading an extra (bad) record. The correct way to deal with this is to put the >> (or getline) operation as the condition in the while statement.
1
2
3
while (stream >> var) // or while (getline(stream,var))
{ // Good operation
}
- can you please elaborate this section with example? are you saying better would be read lines with getline.


Line 86,113,145: You shouldn't be subtracting 1 from gnum/num/bnum. I suspect you're doing this because you're you got an extra record due to looping on eof().
- yes it was reading last name in the file twice.

Line 74,101: If the open fails, you output a message (good), then proceed as if nothing was wrong (bad).
- i think i have to terminate program scan if file open fails to prevent what you are saying. would that be good ?

Thankyou for your input.
i thought vector can work just like array

In many cases, yes. An array will "degrade" to a pointer. Vectors do not.

can you please elaborate this section with example?

Let's take your example of three records in the file. You loop three times, reading each record.
You are now conceptually at eof, however, the eof bit has NOT been set. As I explained, the eof bit is only set when you make a read attempt and there is nothing to read. After reading the three records you return to the top of the loop. eof() is false since you have not made an unsuccessful read attempt. Consequently, you execute the loop a fourth time. Line 80/107 you make a read attempt which sets eof, but you do not check if the read is successful. You then push whatever was in girl/boy onto the vector. This results in a duplicate entry.

are you saying better would be read lines with getline.

No, I'm not saying that. The choice between getline and >> depends on what you're reading. If you want to read something with embedded spaces, then getline is usually the preferred choice.

i think i have to terminate program scan if file open fails to prevent what you are saying. would that be good ?

Yes. exit() is useful for this. Be aware exit() does not cleanup C++ objects with automatic storage duration. Not really an issue in a simple program such as this, but something to keep in mind.
http://www.cplusplus.com/reference/cstdlib/exit
Thank you for sharing your knowledge, i will work on it and update if i have any questions.

Thanks once again.
Topic archived. No new replies allowed.