В первом случае "string"
может храниться в области процесса, доступной только для чтения, поэтому попытка изменить память, указанную p
, приведет к неопределенному поведению.
Во второмВ этом случае фактическая память выделяется и инициализируется в стеке во время выполнения (или в соответствующем разделе процесса при запуске программы, если это не локальная переменная), поэтому изменение памяти в порядке.
Первый случай можетПроиллюстрировать это следующим образом:
+---+ +---+---+---+---+---+---+---+
| | ----> | s | t | r | i | n | g | \0|
+---+ +---+---+---+---+---+---+---+
p
В то время как второй случай:
+---+---+---+---+---+---+---+
| s | t | r | i | n | g | \0|
+---+---+---+---+---+---+---+
p
Эти два объявления имеют существенную разницу, хотя вы, возможно, слышали, что они одинаковы от низкогокниги по программированию качества C.
Первый - это указатель типа char *
, а второй - массив типа char []
.Идентификаторы массива распадаются на указатель в некоторых контекстах, но это не делает их указателями.
Указатель - это просто адрес, а массив - это "все" - в первомcase sizeof(p)
возвращает размер указателя (обычно 4
или 8
в зависимости от целевой машины), а во втором случае - 7 * sizeof(char)
, длину фактической строки.