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

时间:2018-12-16 06:55:44

标签: c string segmentation-fault strcpy string-literals

据我了解,字符串文字存储在只读存储器中,并且在运行时对其进行修改会导致分段错误,但是我的以下代码在编译时不会出现分段错误。

#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) != '\0') {
  s++;
  t++;
  }
}

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

编译器详细信息:

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

2 个答案:

答案 0 :(得分:7)

  

字符串文字存储在只读存储器中,并且在运行时对其进行修改会导致分段错误,

不,您误会了。它调用undefined behaviour,而分段错误是UB可能造成的许多影响之一。

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

  

[...]如果程序尝试修改这样的数组,则行为是   未定义。

答案 1 :(得分:3)

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

因此,段错误不是此UB的唯一可能效果。

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