Вот гипотетическая карта памяти, показывающая, как строковые литералы, массив и указатель все связаны друг с другом:
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
"aaa" 0x00040000 'a' 'a' 'a' 0x00
"bbb" 0x00040004 'b' 'b' 'b' 0x00
"cc" 0x00040008 'c' 'c' 0x00 ???
"dd" 0x0004000C 'd' 'd' 0x00 ???
...
a 0x08000000 'a' 'a' 'a' 0x00
b 0x08000004 0x00 0x04 0x00 0x00
Это ситуация в строке 6 в вашем коде после того, как a
и b
были объявлены и инициализированы. Строковые литералы "aaa"
, "bbb"
, "cc"
и "dd"
все находятся где-то в памяти, так что они существуют на протяжении всей жизни программы. Они хранятся в виде массивов char
(const char
в C ++). Попытка изменить содержимое строкового литерала (в случае этого гипотетического, попытка записи в любую область памяти, начиная с 0x0004) вызывает неопределенное поведение. Некоторые платформы хранят строковые литералы в постоянной памяти, другие хранят их в доступной для записи памяти, но во всех случаях они должны обрабатываться , как если бы они были недоступны для записи.
Объект a
является массивом char
, и он был инициализирован с содержимым строкового литерала "aaa"
. Объект b
является указателем на char
, и он был инициализирован с адресом строкового литерала "bbb"
. В строке
strcpy(a, "cc");
вы копируете содержимое строкового литерала "cc"
в a
; после выполнения строки ваша карта памяти выглядит так:
Item Address 0x00 0x01 0x02 0x03
---- ------- ---- ---- ---- ----
"aaa" 0x00040000 'a' 'a' 'a' 0x00
"bbb" 0x00040004 'b' 'b' 'b' 0x00
"cc" 0x00040008 'c' 'c' 0x00 ???
"dd" 0x0004000C 'd' 'd' 0x00 ???
...
a 0x08000000 'c' 'c' 0x00 0x00
b 0x08000004 0x00 0x04 0x00 0x00
Поэтому, когда вы печатаете a
в стандартный вывод, вы должны увидеть строку cc
. Примечание: printf
буферизуется, поэтому возможно, что вывод не будет записан в терминал сразу - либо добавьте символ новой строки в строку формата (printf("%s\n", a);
), либо вызовите fflush(stdout);
после printf
, чтобы убедиться ваш вывод обнаруживается.
В строке 9 вы пытаетесь скопировать содержимое строкового литерала "dd"
в место, на которое указывает b
; к сожалению, b
указывает на другой строковый литерал, который, как упоминалось выше, вызывает неопределенное поведение. На этом этапе ваша программа может буквально делать все, от запуска, как ожидалось, до полного сбоя, до всего, что между Это может быть причиной того, что вы видите только вывод для cc
.