Когда вы делаете
char* something = "a string literal";
Компилятор помещает "a string literal"
в сам исполняемый образ и просто назначает указатель на эту память на something
.Вам не разрешено изменять эту память, и много раз память, в которой находится строка, помечена только для чтения, поэтому любые попытки записи в нее приводят к нарушению доступа, подобному тому, которое вы испытали.
Когдавы делаете
char something[] = "a string literal";
вы действительно создаете массив в стеке с именами something
и , инициализируя его значением "a string literal"
.Это эквивалентно выполнению char something[] = {'a', ' ', 's', 't', 'r', ..., 'a', 'l', 0};
.Поскольку эта память находится в стеке, вы можете свободно изменять ее.
char* something = "a string literal"
выглядит как
stack executable
------------- ---------------------
|~~~~~~~~~~~| | ~~~~~~~~~~~~~~~~~ |
| something | -----------------> | a string literal0 |
------------- | ~~~~~~~~~~~~~~~~~ |
---------------------
, тогда как char something[] = "a string literal"
выглядит как
stack
-----
|~~~|
| a | <- something is an alias for this location
| |
| s |
| t |
| r |
| i |
| n |
| g |
| |
| l |
| i |
| t |
| e |
| r |
| a |
| l |
| 0 |
-----
Где~~~
означает «другая память и т. Д.».
Обратите внимание, что
char* x = "string literal";
действительно недопустимо и не должно компилироваться, поскольку вы не можете преобразовать char const[x]
в char*
.Это должно быть const char* x
, а не char* x
, но некоторые старые и несовместимые компиляторы ошибочно допускают такое поведение.