0

I'm trying to read file in c and store it in array. After that I need convert to integer related to input. But I got segmentation fault. When I'm looking for reason then I realised that strtok() causes segmentation fault. I tried some of solutions but I could not do that.

My input file is like:

1:2:3:4:5:6
6:5:4:3:2:1

and I store it in array.

Note that: I need to split it by ":" character. And every item must be digit.

then my code is below:

char* line = arr[i];
int d = atoi(strtok(line, ":"));
for ( j = 0; j < SIZE; j++) {
    pushLinkedList(&tmp->P, d);
    d= atoi(strtok(NULL, ":"));  /* This part causes segmentation fault.   */

}

How can i get rid of this fault? Thanks in advance.

YMG
  • 498
  • 6
  • 15

2 Answers2

4

How can you be so sure that it's strtok() which is causing segmentation fault?

Compile and run this program and check the behaviour:

#include <stdlib.h>

int main(void) {
    atoi (NULL);
    return 0;
}

From strtok [emphasis added]:

Return value

Returns pointer to the beginning of the next token or NULL if there are no more tokens.

Look at these statements:

for ( j = 0; j < SIZE; j++) {
    pushLinkedList(&tmp->P, d);
    d= atoi(strtok(NULL, ":"));
    .....
    .....

If SIZE is some value greater than <number of tokens> - 1 then strtok() will return NULL for the nth iteration where n is equal to <number of tokens> in the string.

Since, you have not shown the value of SIZE in code posted, I believe it's greater than the number of tokens in the string processed in the loop. When strtok() finds all the tokens in the given string then all future calls to strtok() will return a NULL pointer and this NULL pointer is passed to atoi() which is resulting in segmentation fault. You should check the strtok() return value and pass it to atoi only when it's not a NULL.

You can do:

int d;
char* line = arr[i];
char* tok = strtok(line, ":");
while (tok) {
    d = atoi(tok);
    pushLinkedList(&tmp->P, d);
    tok = strtok(NULL, ":");
}

Additional:
Why you should not use atoi()?

Community
  • 1
  • 1
H.S.
  • 11,654
  • 2
  • 15
  • 32
  • Yep, that's a good rewrite of the loop, though the jury is still out on `&tmp->P`, which may be right, but may be the source of the segfault -- no way to tell without a MCVE. – David C. Rankin Dec 25 '19 at 05:28
  • @DavidC.Rankin Yes, `&tmp->P` could be source of the segfault but the OP is pointing out the `d = atoi(strtok(NULL, ":"))` statement as cause of segfault in the program comment. But, of course, a MCVE would have assured the cause of segfault. – H.S. Dec 25 '19 at 06:44
3

strtok isn't causing the segfault. atoi is, because you're passing it a null pointer. You need to check whether strtok returns a null pointer and break out of your loop if it does, rather than just blindly handing it to atoi.

  • strtok does not returns a null pointer in my code. But I do not know why it causes. – YMG Dec 25 '19 at 02:16
  • 1
    @YMG with the code you have showed us there is no way you can know if strtok returned a null pointer or not. So claiming "strtok does not returns a null pointer" is not something we can trust. – Zan Lynx Dec 25 '19 at 05:41