I have a vector of a structure, and the structure is a triplet of values.
struct Process
{
int64_t id, arrivalTime, burstTime;
};
vector<Process> parseInputFile(string filename, vector<Process> &vec){
ifstream inFile;
int64_t arrival;
int64_t burst;
inFile.open(filename);
if (!inFile) {
cerr << "Unable to open file datafile.txt";
exit(1); // call system to stop
}
for ( int64_t i = 0; i>=0; i++) {
inFile >> arrival;
inFile >> burst;
if(inFile.eof()){
inFile.close();
cout<<"Size of vector: "<<vec.size()<<endl;
return vec;
}
vec.push_back({i, arrival, burst});
}
return vec;
}
int main(int argc, char * const argv[]){
string algo = argv[1];
string filename = argv[2];
int timeSlice;
vector<Process> vec;
vec = parseInputFile(filename, vec);
for(int i = 0; i <vec.size()+10; i++){
cout<<vec[i].arrivalTime<<" "<<vec[i].burstTime<<endl;
}
}
As you can see above, in for loop, I print out 10 values beyond the size of my vector and This is what I get as output
1 10
3 5
5 3
0 0
51841 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
Even though my file only has the first 3 lines. In my future code I want to be able to look up values in this vector and move them around, which will be impossible if my vector is filled with garbage. How do I ensure that my vector is only filled with values from the input file I give to it?
As the comments mention, you can't just read memory beyond your vector's allocated space and NOT expect garbage. Your RAM will look a bit like this (very simplified):
Address | Value
--------|-------
0x00001 | garbage
0x00002 | 1 <--- vector vec points here (vec[0])
0x00003 | 2
0x00004 | 3 <--- three elements were pushed, so vector vec ends here (vec[2])
0x00005 | garbage
So if you read beyond vec[2]
, you will read random values in RAM which is undefined. That's why you see that garbage in your for loop.
By the way, if the above diagram looks foreign to you, you should probably read some C/C++ tutorials or read up on it in a book.
Lastly, I'm not sure what you're really trying to achieve, but if you want to guarantee that the 10 values after your vector ends are 0, then you have to initialize those values to 0. C++ won't magically do that for you.
You can do this using vec.reserve(N)
where N is the number of elements you want to initialize.
Also, like the comments mentioned, you should pass the vector by reference, not by value. The way you did it, the vector gets copied when it gets passed to your function, the function modifies it and returns the modified copy. Take a look at the below code, where the vector's address gets passed and the function modifies the vector directly without needing to make a copy (saves memory and is faster).
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
struct Process
{
int64_t id, arrivalTime, burstTime;
};
// note the & sign means will pass vec by reference instead of by value
void parseInputFile(string filename, vector<Process>& vec){
ifstream inFile;
int64_t arrival;
int64_t burst;
inFile.open(filename);
if (!inFile) {
cerr << "Unable to open file datafile.txt";
exit(1); // call system to stop
}
for ( int64_t i = 0; i>=0; i++) {
inFile >> arrival;
inFile >> burst;
if(inFile.eof()){
inFile.close();
cout<<"Size of vector: "<<vec.size()<<endl;
break;
}
vec.push_back({i, arrival, burst});
}
}
int main(int argc, char * const argv[]){
string algo = argv[1];
string filename = argv[2];
int timeSlice;
vector<Process> vec;
// initialize and zero 30 elements
vec.reserve(30);
// modify vec by passing it by reference
parseInputFile(filename, vec);
for(int i = 0; i <vec.size()+10; i++){
cout<<vec[i].arrivalTime<<" "<<vec[i].burstTime<<endl;
}
}