4

I am having a segmentation fault while running this code:

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;

class cipher {
    public:
        char letter;
        int frequency;
};

bool comp(const cipher &A, const cipher &B) {
    if(A.frequency<B.frequency)
        return true;
    else
        return false;
}

vector<cipher> cipherF;

int posOf(char c)
{
    int i;
    for(i=0; i<26; ++i)
        if(cipherF[i].letter == c)
            return i;
    return -1;
}

int main()
{
    int t;
    cin >> t;
    string tmp;
    getline(cin, tmp);
    while(t--) {
        cipherF.clear();
        for(int i=97; i<=122; ++i)
        {
            cipher cip;
            cip.letter = i;
            cip.frequency = 0;
            cipherF.push_back(cip);
        }

        string txtF, cipherText;
        getline(cin, txtF);
        getline(cin, cipherText);

        for(int i=0; i<cipherText.size(); ++i)
        {
            char c = tolower(cipherText[i]);
            ++(cipherF[c-97].frequency);
        }

        stable_sort(cipherF.begin(), cipherF.end(), comp);
        for(int i=0; i<cipherText.size(); ++i)
        {
            int pos = posOf(cipherText[i]);
            if(pos == -1)
                continue;
            else if(isupper(cipherText[i]))
                cipherText[i] = toupper(txtF[pos]);
            else
                cipherText[i] = txtF[pos];
        }
        cout << cipherText << endl;
    }
}

The problem is when I run it in GDB, the code runs fine and excellent. Why is this running in GDB without any segmentation fault, but running at every other place with a segmentation fault?

Here is the problem I am trying to solve: http://www.codechef.com/DEC13/problems/CHODE

7
  • You might want to look at possible race conditions Commented Dec 10, 2013 at 13:45
  • what is race condition? Commented Dec 10, 2013 at 13:46
  • @Unbound: a term you can google. Commented Dec 10, 2013 at 13:46
  • Can you narrow down the code at all? Post a shorter testcase here inline? Commented Dec 10, 2013 at 13:47
  • @PaulEvans The code the OP links to is single-threaded. Why would there be races? Commented Dec 10, 2013 at 13:47

1 Answer 1

4

The problem is that your input includes characters that are not in the range [a-Z]. For example: ! That causes the vector to be accessed at invalid indexes.

You can check these things running your program with valgrind.

valgrind ./ideone < stdin
...
==2830== Invalid read of size 4
==2830==    at 0x40111A: main (ideone.cpp:53)
...
==2830== Invalid write of size 4
==2830==    at 0x401120: main (ideone.cpp:53)

The problem is in these lines:

    for(int i=0;i<cipherText.size();++i)
    {
        char c = tolower(cipherText[i]);
        ++(cipherF[c-97].frequency);
    }

c - 97 may be lower than 0.

You can check, for example:

    for(int i=0;i<cipherText.size();++i)
    {
        char c = tolower(cipherText[i]);
        if (c < 'a' || c > 'z') continue;
        ++(cipherF[c-97].frequency);
    }
Sign up to request clarification or add additional context in comments.

3 Comments

Alright, I find the problem, But what is the problem with GDB? as valgrind found the problem so should have GDB, right?
There are some things that GDB changes on the environment for ease of debugging. Valgrind is looking for invalid memory accesses, gdb isn0t. If you enable ASLR in gdb, it will segfault. Try running set disable-randomization off on gdb before debugging your program.
Just remember, valgrind and gdb go together :P. You can even launch gdb after valgrind detects a segfault!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.