Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strcmp segmentation fault

Tags:

c++

c

Here is a problem from spoj. nothing related to algorithms, but just c

Sample Input

2

a aa bb cc def ghi

a a a a a bb bb bb bb c c

Sample Output

3

5

it counts the longest sequence of same words http://www.spoj.pl/problems/WORDCNT/ The word is less than 20 characters But when i run it, it's giving segmentation fault. I debugged it using eclipse. Here's where it crashes

if (strcmp(previous, current) == 0)
                currentLength++;

with the following message

No source available for "strcmp() at 0x2d0100" What's the problem?

#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
using namespace std;
int main(int argc, const char *argv[])
{
    int t;
    cin >> t;
    while (t--) {
        char line[20000], previous[21], current[21], *p;
        int currentLength = 1, maxLength = 1;
        if (cin.peek() == '\n') cin.get();
        cin.getline(line, 20000);

        p = strtok(line, " '\t''\r'");
            strcpy(previous, p);

        while (p != NULL) {
            p = strtok(NULL, " '\t''\r'");
            strcpy(current, p);

            if (strcmp(previous, current) == 0)
                currentLength++;
            else
                currentLength = 1;
            if (currentLength > maxLength)
                maxLength = currentLength;
        }
        cout << maxLength << endl;
    }
    return 0;
}

2 Answers

The problem is probably here:

    while (p != NULL) {
        p = strtok(NULL, " '\t''\r'");
        strcpy(current, p);

While p may not be NULL when the loop is entered.
It may be NULL when strcpy is used on it.

A more correct form of the loop would be:

    while ((p != NULL) && ((p = strtok(NULL, " \t\r")) != NULL))
    {
        strcpy(current, p);

Note. Tokenizing a stream in C++ is a lot easier.

std::string  token;
std::cin >> token;  // Reads 1 white space seoporated word

If you want to tokenize a line

// Step 1: read a single line in a safe way.
std::string line;
std::getline(std::cin, line);

// Turn that line into a stream.
std::stringstream  linestream(line);

// Get 1 word at a time from the stream.
std::string token;
while(linestream >> token)
{
    // Do STUFF
}
like image 93
Martin York Avatar answered Jan 28 '26 15:01

Martin York


Forgot to check for NULL on strtok, it will return NULL when done and you cannot use that NULL on strcpy, strcmp, etc.

Note that you do a strcpy right after the strtok, you should check for null before doing that using p as a source.

like image 44
bcsanches Avatar answered Jan 28 '26 17:01

bcsanches