About Segmentation fault

K

Kies

Hi everyone, these days I find a problem.Look this source code:
1 #include <stdio.h>
2
3 int
4 main(void)
5 {
6 char a[] = "hello";
7 a[0] = 'X';
8 printf("%s\n", a);
9 char *p = "world";
10 p[0] = 'Y';
11 printf("%s\n", p);
12 exit(0);
13 }
It coule compile correctly.But if i run it. it will give me a
Segmentation fault.
More oddly, if i use GDB to dubeg it, i run it step by step, it will
work well, the GDB display: Program exited normally.
Can anyone tell me why does it happen?
 
V

Vladimir S. Oka

Hi everyone, these days I find a problem.Look this source code:
1 #include <stdio.h>
2
3 int
4 main(void)
5 {
6 char a[] = "hello";

This initialises `char` array `a` to {'h', ..., 'o', '\0'}.
7 a[0] = 'X';

It's perfectly legal to modify non-constant array elements.
8 printf("%s\n", a);
9 char *p = "world";

This assigns the address of a constant string literal "world" to a
`char` pointer `p`.
10 p[0] = 'Y';

It is not allowed to modify constants.
11 printf("%s\n", p);
12 exit(0);
13 }
It coule compile correctly.But if i run it. it will give me a
Segmentation fault.
More oddly, if i use GDB to dubeg it, i run it step by step, it will
work well, the GDB display: Program exited normally.
Can anyone tell me why does it happen?

You invoke Undefined Behaviour -- anything can happen.

Look at the <c-faq.com> 8.5 for guidance.
 
B

Ben C

Hi everyone, these days I find a problem.Look this source code:
1 #include <stdio.h>
2
3 int
4 main(void)
5 {
6 char a[] = "hello";
7 a[0] = 'X';
8 printf("%s\n", a);
9 char *p = "world";
10 p[0] = 'Y';

You shouldn't modify string constants. It's better therefore to write:

const char *p = "world";

That way it won't compile, and you know about it sooner.

a[], on the other hand, is a local array, initialized with a string
constant. It's fine to modify a[].
More oddly, if i use GDB to dubeg it, i run it step by step, it will
work well, the GDB display: Program exited normally. Can anyone tell
me why does it happen?

No idea. gdb will normally trap SIGSEGV.
 
K

Keith Thompson

Vladimir S. Oka said:
[...]
9 char *p = "world";

This assigns the address of a constant string literal "world" to a
`char` pointer `p`.
10 p[0] = 'Y';

It is not allowed to modify constants.

More precisely, it's not allowed (i.e., invokes undefined behavior) to
modify string literals. (The term "constants" could mean any of
several things.)
 
R

ranjmis

Kies said:
Hi everyone, these days I find a problem.Look this source code:
1 #include <stdio.h>
2
3 int
4 main(void)
5 {
6 char a[] = "hello";
7 a[0] = 'X';
8 printf("%s\n", a);
9 char *p = "world";
10 p[0] = 'Y';

Since p points to string literal. According to c standard modifying its
value can lead to undefined behavior.
compilers put these literals in read only memory. so if you modify the
value you get segmentaion fault at run time.
 
V

Vladimir S. Oka

ranjmis said:
Kies said:
Hi everyone, these days I find a problem.Look this source code:
1 #include <stdio.h>
2
3 int
4 main(void)
5 {
6 char a[] = "hello";
7 a[0] = 'X';
8 printf("%s\n", a);
9 char *p = "world";
10 p[0] = 'Y';

Since p points to string literal. According to c standard modifying its
value can lead to undefined behavior.

Not "can" -- "does".
compilers put these literals in read only memory. so if you modify the
value you get segmentaion fault at run time.

Not necessarily. That's the beauty of undefined behaviour -- anything
can happen.
 
J

Jack Klein

Hi everyone, these days I find a problem.Look this source code:
1 #include <stdio.h>
2
3 int
4 main(void)
5 {
6 char a[] = "hello";

This initialises `char` array `a` to {'h', ..., 'o', '\0'}.
7 a[0] = 'X';

It's perfectly legal to modify non-constant array elements.
8 printf("%s\n", a);
9 char *p = "world";

This assigns the address of a constant string literal "world" to a
`char` pointer `p`.

While your overall description is correct, your terminology is quite
wrong.

The OP's line 9 causes the creation of an array of 6 characters
containing the string literal. Like all string literals in C, this
array has the type "array of 6 char", and NOT "array of 6 const char".

The type of a string literal in C is always "array of char", and never
"array of const char".
10 p[0] = 'Y';

It is not allowed to modify constants.

Actually, "allowed" is not particularly good wording here. Of course
it is "allowed", it is only that the result is undefined.

But that doesn't apply here, whatever word you use, because p[0] is a
modifiable char, not a const char.

Attempting to modify a string literal produces undefined behavior in C
because the C standard specifically states that face, not because the
array holding the string literal is composed of const chars.
 
V

Vladimir S. Oka

Hi everyone, these days I find a problem.Look this source code:
1 #include <stdio.h>
2
3 int
4 main(void)
5 {
6 char a[] = "hello";

This initialises `char` array `a` to {'h', ..., 'o', '\0'}.
7 a[0] = 'X';

It's perfectly legal to modify non-constant array elements.
8 printf("%s\n", a);
9 char *p = "world";

This assigns the address of a constant string literal "world" to a
`char` pointer `p`.

While your overall description is correct, your terminology is quite
wrong.

I agree, from the pedantic point of view. From the practical point of
view, I'd prefer "loose" -- and IMHO giving the OP just the guidance he
needs.
The OP's line 9 causes the creation of an array of 6 characters
containing the string literal. Like all string literals in C, this
array has the type "array of 6 char", and NOT "array of 6 const char".

I never said "array of 6 const char". Rather loosely, I said "constant
string literal", "constant" being the loose one. I realise just "string
literal" may be more precise, but I wanted to make a point that these
cannot/should not/are not allowed to be modified. I felt this was more
important to the OP.
The type of a string literal in C is always "array of char", and never
"array of const char".
10 p[0] = 'Y';

It is not allowed to modify constants.

Actually, "allowed" is not particularly good wording here. Of course
it is "allowed", it is only that the result is undefined.

Remember that here we're talking to someone who's most likely a novice
programmer. Is it more instructive to tell them "this is undefined
behaviour -- demons fly out of your nose" or "don't do that -- it's not
allowed"? Especially since the explanation of UB must include the
reference to "it is even allowed to work on some implementations, some
of the time", and FWIW, in my experience, novices tend to take that as
a license to experiment, find out that it actually works reliably
(every single one out of ten times they tried) on their tool chain,
exclaim "Cool! On this system it works *faster*!", and leave it for the
maintainer to suffer the consequences.
But that doesn't apply here, whatever word you use, because p[0] is a
modifiable char, not a const char.

Only the one that makes DS9K nuke Mars when written to? Say "modifiable"
and someone is going to do it.
Attempting to modify a string literal produces undefined behavior in C
because the C standard specifically states that face, not because the
array holding the string literal is composed of const chars.

Again "const char" was never mentioned in my post. For UB, see above.

I guess I should be ritually presented with pemo's "not a pedant" sig,
now that Keith wants to strip it off him. ;-)

--
BR, Vladimir

Calvin: "I wonder where we go when we die."
Hobbes: "Pittsburgh?"
Calvin: "You mean if we're good or if we're bad?"
 

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
473,772
Messages
2,569,593
Members
45,112
Latest member
VinayKumar Nevatia
Top