Why a segmentation fault for changing a non-const

2019-07-15 06:26发布

With this code, I get a segmentation fault:

   char* inputStr = "abcde";
   *(inputStr+1)='f';

If the code was:

   const char* inputStr = "abcde";
   *(inputStr+1)='f';

I will get compile error for "assigning read-only location". However, for the first case, there is no compile error; just the segmentation fault when the assign operation actually happened.

Can anyone explain this?

9条回答
甜甜的少女心
2楼-- · 2019-07-15 07:04

The standard states that you are not allowed to modify string literals directly, regardless of whether you mark them const or not:

Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation-defined. The effect of attempting to modify a string literal is undefined.

In fact, in C (unlike C++), string literals are not const but you're still not allowed to write to them.

This restriction on writing allows certain optimisations to take place, such as sharing of literals along the lines of:

char *ermsg = "invalid option";
char *okmsg =   "valid option";

where okmsg can actually point to the 'v' character in ermsg, rather than being a distinct string.

查看更多
我只想做你的唯一
3楼-- · 2019-07-15 07:05

String literals, while officially non-const, are almost always stored in read-only memory. In your setup, this is apparently only the case if it is declared as const char array.

Note that the standard forbids you to modify any string literal.

查看更多
做自己的国王
4楼-- · 2019-07-15 07:17

What happened is that the compiler put the constant "abcde" in some read-only memory segment. You pointed your (non-const) char* inputStr at that constant, and kaboom, segfault.

Lesson to be learned: Don't invoke undefined behavior.

Edit (elaboration)

However, for the first case, there is no compile error, just segmentation fault when the assign operation actually happened.

You need to enabled your compiler warnings. Always set your compiler warnings as high as possible.

查看更多
等我变得足够好
5楼-- · 2019-07-15 07:19

This gets created in the code segment:

char *a = "abcde";

Essentially it's const.

If you wish to edit it, try:

char a[] = "abcde";
查看更多
Melony?
6楼-- · 2019-07-15 07:24

Even though "abcde" is a string literal, which should not be modified, you've told the compiler that you don't care about that by having a non-const char* point to it.

The compiler will happily assume that you know what you're doing, and not throw an error. However, there's a good chance that the code will fail at runtime when you do indeed try to modify the string literal.

查看更多
Lonely孤独者°
7楼-- · 2019-07-15 07:25

String literals are typically stored in read-only memory. Trying to change this memory will kill your program.

Here's a good explanation: Is a string literal in c++ created in static memory?

查看更多
登录 后发表回答