strtok causes Segmentation fault

B

bofh1234

I need to delimit a string. The delimiters are a semicolon and comma.
When I run the program I get a segmentation fault on the first strtok.
I followed the examples of others and from my old C books, but I can't
seem to find the problem. The accesslist has a format of
20,45;22,44;46,28;99,43,etc. What am I doing wrong?
Thanks,

#include <sys/signal.h>

#include <messages.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>

#define or ||
#define and &&

int createvarible(const int sock, char *name, char *type, char *value,
char *list)
{
int n=0, size, returnval=0;
char *tokenptr=NULL, *tokenptr2=NULL;
int accesscode, portnum;

tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?

if (tokenptr == NULL) {
tokenptr2 = strtok(list, ",");//delimit accesscode as there is no
semicolon
accesscode=atoi(tokenptr2);
tokenptr2 = strtok(NULL, ",");//delimit port
portnum=atoi(tokenptr2);
printf("code[0] %d\n", accesscode);
printf("port[0] %d\n", portnum); }
else {
while (tokenptr != NULL) { //don't worry about the code down here it
does what I need
tokenptr2 = strtok(list, ";");//delimit accesscode
accesscode=atoi(tokenptr2);
tokenptr2 = strtok(NULL, ",");//delimit portnum
portnum=atoi(tokenptr2);
printf("code[0] %d\n",accesscode);
printf("port[0] %d\n",portnum);
n++;
}
}
return accesscode;
}
 
V

void * clvrmnky()

I need to delimit a string. The delimiters are a semicolon and comma.
When I run the program I get a segmentation fault on the first strtok.
I followed the examples of others and from my old C books, but I can't
seem to find the problem. The accesslist has a format of
20,45;22,44;46,28;99,43,etc. What am I doing wrong?
Thanks,

#include <sys/signal.h>

#include <messages.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>

#define or ||
#define and &&

int createvarible(const int sock, char *name, char *type, char *value,
char *list)
{
int n=0, size, returnval=0;
char *tokenptr=NULL, *tokenptr2=NULL;
int accesscode, portnum;

tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?
Is list non-null when first used as an arg to strtok()? Is it
null-terminated?
 
J

Joe Smith

void * clvrmnky() said:
Is list non-null when first used as an arg to strtok()? Is it
null-terminated?

Non Standard stuff. Could this question have been framed so as to be
topical in clc? Joe
 
B

bofh1234

Here is how I call createvarible:
createvarible(ss, "xyz", "string", "this is a test",
"22,43;44,33")
So to answer your question the string is null terminated. To null
terminate the string I think I have to put \0 at the end right?

Thanks,
 
B

bofh1234

Changing the function call to createvarible(ss, "xyz", "string", "this
is a test",
"22,43;44,33\0") still causes a seg fault.
 
N

Nelu

Changing the function call to createvarible(ss, "xyz", "string", "this
is a test",
"22,43;44,33\0") still causes a seg fault.

strtok is a surgical function i.e. it destroys the original string that
it works on.
It may not be able to change a const string.

Check these two pieces of code:

p1:

int main(void) {
char *a="something";
a[1]='b';
return 0;
}

p2:

int main(void) {
char a[]="something";
a[1]='b';
return 0;
}

See which one segfaults.
 
V

void * clvrmnky()

Joe said:
Non Standard stuff. Could this question have been framed so as to be
topical in clc? Joe
strtok() is part of string.h. Its behaviour is undefined if called
immediately with NULL (i.e., no valid string used first to prime the
internal objects it uses on subsequent calls).

This is regardless of how "standard" the rest of the code is.
 
B

bofh1234

I understand strtok seg faulting if the FIRST call is with NULL, but in
my case the first call is not NULL. It is
tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?
list is a varible passed to the function.

Thanks,
 
D

Default User

(e-mail address removed) wrote:

Posted elsewhere:

Here is how I call createvarible:
createvarible(ss, "xyz", "string", "this is a test",
"22,43;44,33")
I understand strtok seg faulting if the FIRST call is with NULL, but
in my case the first call is not NULL. It is
tokenptr = strtok(list, ";"); //this line causes the seg fault WHY?
list is a varible passed to the function.

You are passing a string literal as the list parameter, which you then
send to strtok(). This causes undefined behavior.

Also, read the information below.



Brian
 
C

CBFalconer

Here is how I call createvarible:
createvarible(ss, "xyz", "string", "this is a test",
"22,43;44,33")
So to answer your question the string is null terminated. To null
terminate the string I think I have to put \0 at the end right?

Why are you making intelligent commentary virtually impossible by
not including adequate context? See my sig below, even on the
impossible google interface to usenet. Read the referenced URLs
before posting again.

I vaguely remember you were passing some of those parameters to
strtok. strtok modifies the string on which it operates. The
strings you pass above are not modifiable, and any attempt to do so
results in undefined behaviour.

You could search the archives of this group for my "toksplit"
function, which does not have these problems, and could be launched
in that manner. If you reply (in the newsgroup) in the appropriate
format I could even be persuaded to republish it.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
 
B

bofh1234

I understand strtok seg faulting if the FIRST call is with NULL, but
You are passing a string literal as the list parameter, which you then
send to strtok(). This causes undefined behavior.
So?? I tried strtok(*list, ";"); and it still seg faults. According
to my old C book strtok is supposed to take a string for the first
argument. I even tried changing createvarible to:
int createvarible(const int sock, char *varname, char *vartype, char
*initialvalue, char accesslist[64])
and I still get a seg fault. How can I get this thing to work.
 
D

Default User

So?? I tried strtok(*list, ";"); and it still seg faults.

What are you talking about? Do you know what a string literal is? You
can't pass anything that looks like "some text" to a function that will
modify it. You passed a string literal as the list parameter. You can't
do that.


Brian
 
B

bofh1234

I fixed it myself. It may not be pretty but it works. I changed
createvarible back to passing a pointer. I created a local varible
char string[64], and did a strncpy(string,list,64) and did the strtok
on string. All I can say strtok needs some improvements.
 
P

pete

So?? I tried strtok(*list, ";"); and it still seg faults. According
to my old C book strtok is supposed to take a string for the first
argument.

So, there's more involved here than just the rules for strtok.
There's also the rules for strings.
Attempting to modify a string literal is undefined.
Seg fault is a blatant form of undefined behavior.
 
D

Default User

I fixed it myself. It may not be pretty but it works. I changed
createvarible back to passing a pointer. I created a local varible
char string[64], and did a strncpy(string,list,64) and did the strtok
on string.

Which is what I was trying to tell you.



Brian
 
J

Jack Klein

strtok is a surgical function i.e. it destroys the original string that
it works on.
It may not be able to change a const string.

Your last statement is correct, but has nothing directly to do with
the OP's problem.

String literals in C have the type "array of char", and very
specifically do not have the type "array of constant char".

Attempting to modify a string literal in C produces undefined behavior
because the C standard specifically says so, not because, as you
incorrectly think, they are const qualified.
 
N

Nelu

Jack said:
Your last statement is correct, but has nothing directly to do with
the OP's problem.
That's why it crashes at the first call to strtok.
String literals in C have the type "array of char", and very
specifically do not have the type "array of constant char".

Attempting to modify a string literal in C produces undefined behavior
because the C standard specifically says so, not because, as you
incorrectly think, they are const qualified.
Yes. The problem was that I couldn't remember 'string literal'. I guess
I was wrong
trying to replace it with const string. Sorry, about that.
 
V

void * clvrmnky()

You are passing a string literal as the list parameter, which you then
send to strtok(). This causes undefined behavior.
So?? I tried strtok(*list, ";"); and it still seg faults. According
to my old C book strtok is supposed to take a string for the first
argument. I even tried changing createvarible to:
int createvarible(const int sock, char *varname, char *vartype, char
*initialvalue, char accesslist[64])
and I still get a seg fault. How can I get this thing to work.
Think:

char *strtok(char *s1, const char *s2);

The string [s1] passed to strtok() must be mutable, because it is a
destructive function. Your appear to be passing the function a static
buffer or literal string.

Slow down a bit and re-read all the comments posted so far.

Consider:

[...]
char *fnord = "Fnord Motor Company";
fnord[0] = 'f'; /* Undefined behaviour */
[...]

Can you legally modify fnord, even with a direct assignment? If not,
what about a library function like strtok()?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,044
Messages
2,570,388
Members
47,052
Latest member
ketan

Latest Threads

Top