据我了解,字符串文字存储在只读存储器中,并且在运行时对其进行修改会导致分段错误,但是我的以下代码在编译时不会出现分段错误。
#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)
答案 0 :(得分:7)
字符串文字存储在只读存储器中,并且在运行时对其进行修改会导致分段错误,
不,您误会了。它调用undefined behaviour,而分段错误是UB可能造成的许多影响之一。
引用C11
,第6.4.5 / P7章,字符串文字
[...]如果程序尝试修改这样的数组,则行为是 未定义。
答案 1 :(得分:3)
许多系统上的字符串文字都放在RO内存位置。在最流行的操作系统下(Windows,Linux,mac os等),最流行的编译器可以执行此操作。但是其他许多(例如avr-gcc)却没有。
因此,段错误不是此UB的唯一可能效果。
但是在您的情况下,我敢打赌,编译器已经优化了strcpy调用,因为不需要将对象复制到自身。