I am using strtok(...) of the library and it appears to be working fine until the end condition, where it results in a segmentation fault and program crash. The API claims that strtok(...) will output a NULL when there are no more tokens to be found, which meant, I thought, that you had to catch this NULL in order to terminate any loops that you were running using strtok(...). What do I need to do to catch this NULL to prevent my program from crashing? I imagined the NULL was allowed for use as a terminating condition.
I have prepared a SSCCE for you to observe this behavior. I need strtok(...) to work for a much larger piece of software I am writing, and I am getting the exact same segmentation behavior. The output at the command line is shown below this code vignette (yes I know you use <...> to enclose libraries, but I was having difficulty getting this post to display the code libraries). I am using gcc version 4.5.3, on a Windows 8 OS, and below shows two different flavors of how I imagine one could try to catch the NULL in a loop.
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
main(){
char* from = "12.34.56.78";
char * ch = ".";
char * token = strtok(from, ch);
printf("%s\n",token);
while(token != NULL){
token = strtok(NULL, ch);
printf("%s\n", token);
}
printf("Broke out of loop!");
while(strcmp(token, 0) != 0){
printf("%s\n",token);
token = strtok(NULL, ch);
}
}
############ OUTPUT: ############ $ ./test 12 34 56 78 Segmentation fault (core dumped)
If purpose of code is only to print element separated by '.', Only change in char declaration and before printing token check for its value NULL or not !
OUTPUTThe problem is that even though you terminate the loop when
strtok()
returnsNULL
, you try to print theNULL
first:It turns out there are several opportunities in addition to this one for segfaults in this example, as pointed out by other answers.
Here's one way to handle your example tokenization:
You have both memory access errors and logic errors. I will only address the memory access errors that are causing your program to crash.
strtok
modifies it's first argument. Since you are passing in a string literal, it is unable to modify the string (string literals are not modifiable.)Here's a possible fix to define
from
as a modifiable string array:Because
strtok
modifies the string passed into it, you cannot process that string again in your second while loop. You are essentially passing in a NULL into thestrcmp
function there. A possible fix would be to copy thefrom
array into another buffer each time you wish to usestrtok
.you are first checking if
token
is not equal to NULL(when it is, it breaks out of thewhile
loop). Then you are comparingtoken
, which is aNULL
with a constant NUMBER? here:strcmp(token, 0)
whenstrcmp
expects 2 strings, you provide a number.strcmp
will try to fetch a string at 0th address(or NULL) giving you a segmentation fault.Also this piece of code should be something like the following:
change
to
This is a problem:
You're checking for NULL, but then calling
strtok
again and not checking after that but before printing.There are other problems with the code, but I suspect this is why it crashes where it does now.
strtok
modifies its first argument. You are passing it a string from read-only memory, and the segfault occurs whenstrtok
tries to change it. Try changing from:to