I am trying to read words in from a dictionary file and I am receiving a segfault on my 4th line reading in from the file. From what I have read about vectors in c++ to use the insert command I need to specify an iterator to use as a place holder. To do this is I instantiate an iterator at the beginning of my vector as such.
vector<string>::iterator it = dictionaryFile.begin();
Inside of my for loop I increment where the iterator is pointing by using the increment operator
it++;
I am basing this off of the examples on http://www.cplusplus.com. The iterator works for the first 3 lines then the segfault occurs. I have double checked my file to make sure there are no erroneous characters that are being read in by getline. I believe this error has to do with the call to reserve that I make to ensure there is no overflow of the vector.
Since I am not using the keyword new when it is declared is the vector limited to a capacity of 5? I cannot find any examples of the new keyword being used though!
I have included the segment of code that causes this error. Please note I have re-designed this several times in an attempt to resolve this segfault and this was not my original implementation. I would appreciate any insight a master of c++ might have. Thank you for your time.
vector<string> dictionaryFile (5, ""); //Declaration of vector that will hold the words in the dictionary
ifstream input; //Declaration of input file stream
input.open(inst.c_str());
/********************** Test to see if file was opened ********************************/
if(!input){
cerr << "The file " << inst <<" does not exists in this directory" << '\n';
}
/********************** File is successfully opened**********************************/
string temporaryProcessingString = ""; //This string will temporarily hold values read in from the file
vector<string>::iterator it = dictionaryFile.begin(); //Creates iterator to step through the vector and fix this wild shit
for(int i = 0; getline(input, temporaryProcessingString); i++){ //See I can follow directions given in class no eof used.
cout << "Does this print before SegFault 1 " << endl;
if(dictionaryFile.size() >= (dictionaryFile.capacity() - dictionaryFile.size()) ){ //If current size is greater the 50% capacity reserve size*2 more memory
int oldSize;
oldSize = dictionaryFile.size();
cout << "Does this print before SegFault 2 " << endl;
dictionaryFile.reserve(oldSize + oldSize); //Reservation new capacity for vector containing dictionary
}
/** this is a test bracket that solely keeps track of the vectors size and capacity in the terminal COMMENT OUT BEFORE SUBMITTING*/
cout << "________________________________________________" << '\n';
cout << "Loop Run: " << i << endl;
cout << "Size: " << dictionaryFile.size() << ", Capacity: " << dictionaryFile.capacity() << endl;
cout << "________________________________________________" << '\n';
dictionaryFile.insert(it, temporaryProcessingString); /*******************************THIS LINE CAUSES THE SEGFAULT! UNFORTUNATELY IT IS ALSO THE LINE THAT MOVES THE DATA INTO THE VECTOR************************/
it++;
cout << "Dictionary Entry: " << dictionaryFile[i] << endl;
}
cout << "Dictionary Entry Primary Test: " << dictionaryFile[0] << endl;
When your vector’s size approaches its current capacity (or, in your case, when you call
vector::reserve, see the section on iterator validity here), an internal algorithm will re-allocate it and potentially move it somewhere else, making all iterators to elements in the vector invalid.As your program only seems to insert at the end anyways, use
vector::push_backinstead ofvector::insertto prevent this. You can then also skip thereserveing – the internal algorithms are quite good (you don’t have to be afraid of the vector doing reallocation for every single new element – the algorithms are smarter than that).