strtok problem #5

  • Follow


I've used this function before but I'm suddenly getting bus errors:

%% cat tok.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc,char **argv)
{
  char *c,*fs; const char *sep = ",";

  fs = "5,1";
  c = strtok(fs,sep);
  printf("1st: <%s>\n",c);

  return 0;
}
  %% cc tok.c ; a.out
Bus error

According to gdb the problem occurs in strtok, and the program "works"
if the separator string does not contain characters that are in the test
string.

This problem happens on Mac OS X (Apple-modified gcc 4), gcc 3.something
on Linux, but not with IBM's compiler on a Power5.

Anyone any idea what is happening here?

Victor.
-- 
Victor Eijkhout -- eijkhout at tacc utexas edu
ph: 512 471 5809
0
Reply see449 (230) 5/15/2006 12:13:34 AM

Victor Eijkhout <see@sig.for.address> wrote:

> int main(int argc,char **argv)
> {
>   char *c,*fs; const char *sep = ",";

>   fs = "5,1";

This line is the problem.  Although your compiler will not complain
about this assignment, since string literals in C are not "const", you
may not modify string literals.  strtok() modifies its first argument,
so you are illegally attempting to modify a string literal.  If the
separator string isn't found in the test string, the test string is
not modified; hence the behavior you observed.

In your example, the problem can be completely solved thus:

char fs[]="5,1";

This is not the same as the code you posted; can you see the difference?

>   c = strtok(fs,sep);
>   printf("1st: <%s>\n",c);

>   return 0;
> }

> This problem happens on Mac OS X (Apple-modified gcc 4), gcc 3.something
> on Linux, but not with IBM's compiler on a Power5.

Modifying a string literal results in undefined behavior, one possible
manifestation of which is the program working on some platforms but
not others.

-- 
Christopher Benson-Manica  | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org    | don't, I need to know.  Flames welcome.
0
Reply ataru3909 (237) 5/15/2006 1:28:05 AM


Victor Eijkhout wrote:
> 
> I've used this function before but I'm suddenly getting bus errors:
> 
> %% cat tok.c
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> 
> int main(int argc,char **argv)
> {
>   char *c,*fs; const char *sep = ",";
> 
>   fs = "5,1";
>   c = strtok(fs,sep);
>   printf("1st: <%s>\n",c);
> 
>   return 0;
> }
>   %% cc tok.c ; a.out
> Bus error
> 
> According to gdb the problem occurs in strtok, and the program "works"
> if the separator string
> does not contain characters that are in the test
> string.
> 
> This problem happens on Mac OS X
> (Apple-modified gcc 4), gcc 3.something
> on Linux, but not with IBM's compiler on a Power5.
> 
> Anyone any idea what is happening here?

You're attempting to modify a string literal, 
which is undefined to do.

#include <stdio.h>
#include <string.h>

int main(void)
{
  char *c; 
  const char *sep = ",";
  char fs[] = "5,1";

  c = strtok(fs, sep);
  printf("1st: <%s>\n", c);
  return 0;
}


-- 
pete
0
Reply pfiland (6613) 5/15/2006 1:38:17 AM

Christopher Benson-Manica <ataru@ukato.freeshell.org> wrote:

> strtok() modifies its first argument,

Oh darn. I knew that......

> so you are illegally attempting to modify a string literal. 

.....so I should have realized that. Thanks for pointing it out.

But I'm wondering what happens on a deep level. A string literal is not
a piece lf malloc'ed memory? What is it, then? Or is it allocated in
read-only memory, and the OS balks when I try to write in it?

Victor.
-- 
Victor Eijkhout -- eijkhout at tacc utexas edu
ph: 512 471 5809
0
Reply see449 (230) 5/15/2006 6:11:38 AM

Victor Eijkhout opined:

> Christopher Benson-Manica <ataru@ukato.freeshell.org> wrote:
> 
>> strtok() modifies its first argument,
> 
> Oh darn. I knew that......
> 
>> so you are illegally attempting to modify a string literal.
> 
> ....so I should have realized that. Thanks for pointing it out.
> 
> But I'm wondering what happens on a deep level. A string literal is
> not a piece lf malloc'ed memory? What is it, then? Or is it allocated
> in read-only memory, and the OS balks when I try to write in it?

What happens on a "deep level" is implementation specific. You may be
able to find out in your documentation or ask where your
implementation is discussed. 

However, as far as Standard C is concerned, you shouldn't really care,
apart from the fact that it's illegal to modify string literals.

[E.g. & OT: an embedded compiler may indeed decide to put string
literals in physically read-only memory, OTH on most hosted
implementations it may be in the area of memory which the underlying
OS protects from being written to].

-- 
There are no threads in a.b.p.erotica,  so there's no  gain in using a
threaded news reader.
(Unknown source)

<http://clc-wiki.net/wiki/Introduction_to_comp.lang.c>

0
Reply novine (983) 5/15/2006 6:47:08 AM

Victor Eijkhout wrote:
> 
> Christopher Benson-Manica <ataru@ukato.freeshell.org> wrote:
> 
> > strtok() modifies its first argument,
> 
> Oh darn. I knew that......
> 
> > so you are illegally attempting to modify a string literal.
> 
> ....so I should have realized that. Thanks for pointing it out.
> 
> But I'm wondering what happens on a deep level. A string literal is not
> a piece lf malloc'ed memory? What is it, then? Or is it allocated in
> read-only memory, and the OS balks when I try to write in it?
> 
These are implementation issues. It does *not* matter how the
error is detected. The standard says do *not* do it....so do *not*
do it.

--
+----------------------------------------------------------------+
|   Charles and Francis Richmond     richmond at plano dot net   |
+----------------------------------------------------------------+
0
Reply richchas2 (312) 5/15/2006 6:48:43 AM

5 Replies
54 Views

(page loaded in 0.153 seconds)


Reply: