I was working on an assignment from Alex Allain's Jumping into C++, Exercise 1 of Chapter 19. The user enters a bunch of text (a "haystack"), then enters some other text (a "needle"). The program then tells the user how many times the needle appeared in the haystack.
Everything was going well; I tested a bunch of inputs, and things seemed to work. But, when using the needle "roo" against the haystack "inacatroofcatdogcatyocareler", the program crashes when it gets to the last "r" in the haystack. Here's the function:
Code:
/*
Notes:
strSize = string::size_type typedef
conStrIter = string::const_iterator typedef
strIter = string::iterator typedef
*/
strSize needleCounter(const string& needle, const string& haystack)
{
//if the haystack has less letters than the needle, there are no more
//instances of the needle to find, so...
if (haystack.length() < needle.length())
return 0; //we're done here!
//iterate through the haystack
conStrIter iter;
conStrIter secondIter;
const conStrIter endOfHaystack = haystack.end();
strSize charCount = needle.length();
char firstLetter = needle[0]; //we find the needle based on its first letter
for (iter = haystack.begin(); iter < endOfHaystack; iter++)
{
if (*iter == firstLetter) //if we find the first letter of the needle,
{
//set up a string that includes that letter, and all the ones after
//(based on how many letters in the needle there are)
secondIter = iter + charCount; //get to the where the last letter of the needle may be
//if the second iter gets to or past the endpoint of the haystack, there
//are no instances of the needle from here onward, so...
if (secondIter >= endOfHaystack)
return 0; //we're done here!
//otherwise, just take the letters, and see if it is our needle
string needleSub(iter, secondIter);
if (needleSub == needle) //if we found a needle,
{
//call this function again, passing a haystack without all the letters up to
//the end of the needle
string newHaystack(secondIter, endOfHaystack);
return 1 + needleCounter(needle, newHaystack);
}
else //otherwise, save some resources by moving the iter just before the end of needleSub
{
iter = secondIter - 1;
}
}
}
return 0;
//^this happens when the needle couldnt be found anywhere in the given haystack, despite
//all the other measures in place
}
The bug is on the line:
Code:
secondIter = iter + charCount; //get to the where the last letter of the needle may be
Where the iterator meant to point to the last character in a substring gets made to point to said character. For some reason, before that iterator is even bounds-checked, the program crashes when it processes that line. Only when that last "r" in the haystack is reached, which at the time, was also pointed to by the variable iter.
Which is weird; not only did it work perfectly fine in other inputs in the same haystack, I even tested this iterator-setting in a separate file; setting an iterator past the end of a container shouldn't cause a crash unless you try to access what it is pointing to.
I'd very much appreciate help figuring this out.