Karthik Balakrishnan
Karthik Balakrishnan

Reputation: 4393

C++ program crashes on rotating string by more than it's length

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

Answers (3)

Filip Ros&#233;en
Filip Ros&#233;en

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

nikolas
nikolas

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

Paul Evans
Paul Evans

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

Related Questions