C strcpy() 复制字符串文字而没有分段错误

C strcpy() copies string literals without segmentation fault

据我了解,字符串文字存储在只读内存中,在运行时修改它会导致分段错误,但我的以下代码编译时没有分段错误。

#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 书 strcpy() 实现类似于下面

void strcpy(char *s, char *t)
{
while ((*s = *t) != '[=12=]') {
  s++;
  t++;
  }
}

如果是这样,我应该在这两种情况下都遇到了分段错误。

编译器详细信息:

gcc 版本 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04)

string literals are stored in read-only memory and modifying it during runtime leads to a segmentation fault,

不,你错了。它调用 undefined behaviour,分段错误是 UB 的众多 可能影响之一。

引用 C11,章节 §6.4.5/P7,字符串文字

[...] If the program attempts to modify such an array, the behavior is undefined.

许多系统上的字符串文字都放在 RO 内存位置。 most 个流行的编译器在 most 个流行的操作系统下执行(Windows、Linux、mac os 等)。但是许多其他的(例如 avr-gcc)没有。

因此,段错误并不是此 UB 的唯一影响os。

但在你的情况下,我敢打赌编译器已经优化了 strcpy 调用,因为不需要将对象复制到自身。