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, поскольку копирование объекта в себя не требуется.

Другие вопросы по тегам