C strcpy() копирует строковые литералы без ошибки сегментации
Насколько я понимаю, строковые литералы хранятся в постоянной памяти, и их изменение во время выполнения приводит к ошибке сегментации, но мой приведенный ниже код компилируется без ошибки сегментации.
#include <string.h>
#include <stdio.h>
int main() {
char* scr = "hello";
strcpy(scr,scr);
printf("%s\n",scr);
return 0;
}
вывод: привет
То же самое, если я попытался скопировать исходную строку в разные целевые строковые литералы, это вызовет ошибку сегментации
#include <string.h>
#include <stdio.h>
int main() {
char* scr = "hello";
char* dst = "hello";
strcpy(dst,scr);
printf("%s\n",dst);
return 0;
}
вывод: ошибка сегментации (ядро сброшено)
в соответствии с K&R book strcpy() реализация похожа на ниже
void strcpy(char *s, char *t)
{
while ((*s = *t) != '\0') {
s++;
t++;
}
}
если это так, я должен был получить ошибку сегментации для обоих случаев.
Детали компилятора:
gcc версия 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)
2 ответа
строковые литералы хранятся в постоянном запоминающем устройстве, и его изменение во время выполнения приводит к ошибке сегментации,
Нет вы ошибаетесь Это вызывает неопределенное поведение, и ошибка сегментации является одним из многих возможных эффектов UB.
квотирование C11
Глава §6.4.5/P7, Строковые литералы
[...] Если программа пытается изменить такой массив, поведение не определено.
Строковые литералы во многих системах размещаются в ячейках памяти RO. Это делают самые популярные компиляторы под наиболее популярные ОС (Windows,Linux, Mac OS и т. Д.). Но многие другие (например, avr-gcc) этого не делают.
Таким образом, segfault - не единственный возможный эффект этого UB.
Но в вашем случае я уверен, что компилятор оптимизировал вызов strcpy, поскольку копирование объекта в себя не требуется.