1

The following piece of code produces a segmentation fault during compilation:

(gdb) run
Starting program: /home/anna/Desktop/a.out
Program received signal SIGSEGV, Segmentation fault.
0xb7e97845 in strtok () from /lib/i386-linux-gnu/libc.so.6

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

main () {
char * sentence = "This is a sentence.";
char * words[200] ;
words[0] = strtok(sentence," ");
}

After changing the 5th line, no error is thrown.

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

main () {
char  sentence[] = "This is a sentence.";
char * words[200] ;
words[0] = strtok(sentence," ");
}

Why is this happening?

akjoshi
  • 15,374
  • 13
  • 103
  • 121
anna
  • 585
  • 1
  • 6
  • 22
  • 1
    Note: You're *executing* the program, the compilation has already successfully created the `a.out` file. It does *not* segfault "during compilation". – unwind Dec 20 '12 at 11:44
  • 1
    @WhozCraig This is not a duplicate of that question - the code in the linked question is not actually writing to a string literal, despite the title. – interjay Dec 20 '12 at 12:00
  • @interjay good point. this question is asked at least a couple of times a day. you would think it would be easily findable among the dupes. i'll keep searching. thanks. – WhozCraig Dec 20 '12 at 12:07
  • @interjay how's [this one](http://stackoverflow.com/a/8302326/1322972) instead ? – WhozCraig Dec 20 '12 at 12:10
  • @WhozCraig Yeah that seems better. I'm still not sure if this one should be closed though since the fact that `strtok` modifies the string may not be obvious. – interjay Dec 20 '12 at 12:20
  • @interjay I hope it is, since the highest up-voted answer doesn't mention it at all (`strtok()`, i mean). – WhozCraig Dec 20 '12 at 12:23
  • That's why initializing a pointer to non-`const` `char` with a string literal is poor and dangerous practice, qualify it as `const char *`. Compilers could have many warnings that could help you avoid this problem, `gcc` has `-Wwrite-string` for example. – effeffe Dec 20 '12 at 13:05
  • 1
    Welcome to SO. It should be `int main(void)`. Generally I have the idea that first reading a bit about C could help you a lot. – Jens Gustedt Dec 20 '12 at 13:31

2 Answers2

6
char * sentence = "This is a sentence.";

sentence is a pointer pointing to a string literal "This is a sentence." is stored in a read only memory and you should not be modifying it.
Modifying a string literal in any way results in Undefined Behavior and in your case it manifests in a segmentation fault.

Good Read:
What is the difference between char a[] = ?string?; and char *p = ?string?;?

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
2

Read the man page of strtok (BUGS section),

  • These functions modify their first argument.
  • These functions cannot be used on constant strings.

and char *sentence = "This is a sentence"; is allocated in read-only context, so treated as contant.

Adeel Ahmed
  • 1,591
  • 8
  • 10