SIGSEGV on codechef

I submitted this code for this challenge https://www.codechef.com/problems/CHEFCHR and got a SIGSEGV fault though the code works fine on my VS 2017 - though I don't have an input file with 200000 lines
Codechef use GCC 6.3 with O2 lm fomit-frame-pointer pthread
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
  int num_tests;
  const string pattern("chef");
  cin >> num_tests;
  cin >> ws;
  string input;
  for (int i = 0; i < num_tests; ++i)
  {
    getline(cin, input);
    int count = 0;
    for (size_t j = 0; j < input.size() - 3; ++j)
    {
      if (is_permutation(&input[j], &input[j+4], pattern.begin(), pattern.end()))
        count++;
    }
    if (count > 0)
      cout << "lovely " << count << endl;
    else
      cout << "normal" << endl;
  }
}

Can anyone spot a problem ?
If input.size() == 4 then input[j+4] is out of bounds when j == 0.

If input.size() < 3 then input.size()-3 will wrap around and become a very large value (because input.size() returns an unsigned type) so the loop condition will be true and the loop will run and access string elements out of bounds, until it probably crashes.
Last edited on
When fixing those, do consider that the 3 and 4 are magic constants, but size of the pattern is your true goal.

Furthermore, is there a practical difference in:
1
2
3
is_permutation( &input[j], &input[j+4], pattern.begin(), pattern.end() )
// vs
is_permutation( pattern.begin(), pattern.end(), &input[j], &input[j+4] )
@Peter87, @keskiverto,

thanks it's working now. I even got 100% :)
Here's the solution in case someone is interested.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>

using namespace std;

int main()
{
  int num_tests;
  const string pattern("chef");
  cin >> num_tests;
  cin >> ws;
  string input;
  for (int i = 0; i < num_tests; ++i)
  {
    getline(cin, input);
    int count = 0;
    if (input.size() < pattern.size())
    {
      cout << "normal" << endl;
      continue;
    }
    for (size_t j = 0; j < input.size() - 3; ++j)
    {
      if (is_permutation(pattern.begin(), pattern.end(), &input[j], &input[j + 4]))
        count++;
    }
    if (count > 0)
      cout << "lovely " << count << endl;
    else
      cout << "normal" << endl;
  }
}

Time to run: 0.30sec
Memory consumed: 15240KB
Topic archived. No new replies allowed.