0

I am trying to tokenize a string and insert one token as the key and the rest as values of a map. But while inserting, I get a segmentation fault. I debugged for a long time but could not find a way to overcome this error. Here is my code:

while (!fin.eof())
{
    char *str1;
    char buf[MAX_CHARS_PER_LINE];
    fin.getline(buf, MAX_CHARS_PER_LINE);
    str1 = new char[strlen(buf)];
    int n = 0;
    char *token[MAX_TOKENS_PER_LINE] = {};

    token[0] = strtok(buf, DELIMITER);

    if (token[0])
    {
        for (n = 1; n < MAX_TOKENS_PER_LINE; n++)
        {
            token[n] = strtok(0, DELIMITER);
            if (!token[n]) break;
        }
    }

    // Forming str1 using the tokens here   
     strcpy(str1, token[0]);
     strcat(str1, ":");
     strcat(str1, token[1]);
     int key = atoi(token[3]);

    // Adding str1 to map
     nameId[key] = str1;
   }
}

Any help would be appreciated!

Ashwath
  • 19
  • 5
  • 1
    `while (!fin.eof())` will only end in heartbreak. Test if the read fails, not before the read so you don't process bad data. https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong – Retired Ninja Jul 19 '17 at 03:11
  • Why are you not using `std::string`, or at the very least, storing `std::string` in the map? – PaulMcKenzie Jul 19 '17 at 04:08

1 Answers1

1

After further debugging, I figured out the exact problem. I did not check if the tokens were NULL before concatenating them with str1. After I enforced that check, str1 always gets a valid value and hence, gets inserted in the map.

Here is my updated code:

while (!fin.eof())
{
    char *str1;
    char buf[MAX_CHARS_PER_LINE];
    fin.getline(buf, MAX_CHARS_PER_LINE);
    str1 = new char[strlen(buf)];
    int n = 0;
    char *token[MAX_TOKENS_PER_LINE] = {};

    // Enforcing NULL check for buf
    if (buf)
    {
        token[0] = strtok(buf, DELIMITER);
    }

    // Enforcing the NULL check for the tokens
    if (token[0])
    {
        for (n = 1; n < MAX_TOKENS_PER_LINE; n++)
        {
            token[n] = strtok(0, DELIMITER);
            if (!token[n]) break;
        }

        pair<map<int, char *>::iterator, bool> result;

        // Forming str1 using the tokens here
        strcpy(str1, token[0]);
        strcat(str1, ":");
        strcat(str1, token[1]);

        // Adding str1 to map
        int key = atoi(token[3]);
        nameId[key] = str1;
    }
}
Ashwath
  • 19
  • 5
  • 1
    Now, all you have to do is figure out is [why `while (fin.feof())` is always a bug](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong). – Sam Varshavchik Jul 19 '17 at 02:55