Вы путаете указатель и распределение:
char*
- указатель на некоторый символ в некотором месте в нашей памяти (это может быть или не быть кучей) - постоянная память, такая строка (
"CD"
) - динамическое выделение в куче.
Хотя указатель может указывать либо на константу, либо на кучу, вы можете выполнить ту же операцию (например,: в вашем примере присвойте 0 с помощью 'S').Это не означает, что он всегда будет работать во время выполнения: они могут быть некоторой защитой от этого.
В худшем примере:
char* a = "CD";
char* b = "ZZ";
strcpy(a, "EFGHAAAAAAAAAAAA"); // may fail with Segmentation fault
printf("a: %3s, b: %3s\n", a, b); // may not work
Использование gcc (Gentoo 7.3.0-r3 p1.4) 7.3.0 и запуск программы приводят к Ошибка сегментации прямо на strcpy
.
Вы можете использовать strcpy
только в выделенной памяти:
char* a = malloc(3*sizeof(char)) ;
strcpy(a, "EFGHAAAAAAAAAAAA"); // may fail with Segmentation fault
printf("a: '%s'\n", a); // print a: 'EFGHAAAAAAAAAAAA'
При этом вы вышли за пределы: память, указанная символом a, может хранить до 3 символов, причем последним является \0
.
. В этом случае (всегда?) следует использовать strncpy
вместо:
char* a = malloc(3*sizeof(char));
strncpy(a, "EFGHAAAAAAAAAAAA", 3 );
a[2] = 0;
Кроме того, вы, вероятно, никогда не должны использовать char*
с постоянной строкой, но const char*
(компилятор может уже предупредить вас об этом, если не использовать -Wall
):
const char* a = "CD" ;
a[0] = 'S' ; // should not compile