c-Printf输出超出指定数组长度的字符



我尝试了这段代码:

char string_one[8], string_two[8];
printf("&string_one == %pn", &string_one);
printf("&string_two == %pn", &string_two);
strcpy(string_one, "Hello!");
strcpy(string_two, "Long string");
printf("string_one == %sn", string_one);
printf("string_two == %sn", string_two);

得到了这个输出:

&string_one == 0x7fff3f871524
&string_two == 0x7fff3f87151c
string_one == ing
string_two == Long string

由于第二个字符串长度值大于相应数组的指定大小,因此下标值大于指定数组大小的字符存储在下一个字节中,如地址所示,这些字节属于第一个数组。显然,第一个字符串被覆盖了。第二个数组不可能容纳整个字符串,因为它太大了。然而,输出会打印整个字符串。我推测了一段时间,得出的结论是printf()函数一直输出下一个字节中的字符,直到遇到字符串终止符''。我没有找到任何可供我思考的证据,所以问题是这些猜测是否正确?

来自C标准(5.2.1字符集(

2在字符常量或字符串文字中,执行的成员字符集应由源字符集或由反斜杠\后面跟着一个或多个字符包含所有位的字节设置为0,称为null字符,应存在于基本执行字符集;它用于终止字符串

和(7.21.6.1 fprintf函数(

8转换说明符及其含义为:

s如果不存在l长度修饰符,则参数应为指针到字符类型数组的初始元素。273(字符从数组写入到(但不包括(终止null字符

我的编译器(GCC(说:

警告:"__builtin_memcpy"将12个字节写入大小为8的区域会溢出目标[-Wstringop overflow=]strcpy(字符串_二,"长字符串"(;

为了展示优化将如何利用你认为你知道的一切并彻底改变它,下面是如果你在带有gcc -O3 -flto的64位PowerPC Power-9(又名非x86(上编译它会发生什么

$ ./char-array-overlap
&string_one == 0x7fffc502bef0
&string_two == 0x7fffc502bef8
string_one == Hello!
string_two == Long string

因为如果你看一下机器代码,它根本不会执行strcpy

最新更新