Reputation: 4393
string half_password = password.str();
if(shift < 0) //left shift
rotate(half_password.begin(), half_password.begin() + (-1*shift), half_password.end());
if(shift > 0) //right shift
rotate(half_password.rbegin(), half_password.rbegin() + shift, half_password.rend());
Now, if |shift| > 7 and the length of half_password
is 8, then my program crashes with a segmentation fault. My question is does the rotate
function not allow rotation more than the highest index of the string?
I don't have a problem with this, the logic works fine. I would like to know if this is how the rotate
function works though.
Upvotes: 2
Views: 204
Reputation: 63852
The 2nd argument to std::rotate
is an iterator pointing to the element you'd like to be at the beginning of the string, with that said it's fairly easy to understand that giving it an iterator to an element passed the end/beginning of your container will result in a crash.
You can circumenvent this issue by using the modulus operator %
to limit the result of adding shift
to always be in-between 0
and one less than the length of your container.
#include <iostream>
#include <algorithm>
#include <string>
std::string
shift_it (std::string const& src, int shift)
{
std::string dst = src;
if (shift < 0)
std::rotate (dst.begin (), dst.begin () + (+shift % dst.size ()), dst.end ());
else
std::rotate (dst.rbegin (), dst.rbegin () + (-shift % dst.size ()), dst.rend ());
return dst;
}
int
main (int argc, char *argv[])
{
std::cerr << shift_it ("hello", 7) << std::endl;
std::cerr << shift_it ("hello", 2) << std::endl;
std::cerr << shift_it ("hello", -7) << std::endl;
std::cerr << shift_it ("hello", -2) << std::endl;
}
output:
lohel
lohel
llohe
llohe
Upvotes: 1
Reputation: 8975
From cppreference.com
A precondition of this function is that [first, n_first) and [n_first, last) are valid ranges.
When you are beyond the highest index size, or below the lowest index size, these are not valid ranges.
Upvotes: 3
Reputation: 27577
The second parameter is the middle, so it should lay between the beginning and end. Do a <middle value> % (end() - begin())
to make sure of that.
Upvotes: 1