printf 输出超出数组指定长度的字符

Printf outputs characters beyond the specified length of the array

我试过这段代码:

char string_one[8], string_two[8];
printf("&string_one == %p\n", &string_one);
printf("&string_two == %p\n", &string_two);
strcpy(string_one, "Hello!");
strcpy(string_two, "Long string");
printf("string_one == %s\n", string_one);
printf("string_two == %s\n", string_two);

得到这个输出:

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

由于第二个字符串长度值大于指定数组大小,下标值大于指定数组大小的字符存储在下一个字节中,属于第一个数组作为地址展示。显然第一个字符串被覆盖了。 第二个数组无法容纳整个字符串,它太大了。然而,输出打印了整个字符串。 我推测了一会儿,得出的结论是 printf() 函数一直从下一个字节开始输出字符,直到遇到字符串终止符 '[=13=]'。我的思考没有得到任何证实,所以问题是这些猜测是否正确?

来自 C 标准(5.2.1 字符集)

2 In a character constant or string literal, members of the execution character set shall be represented by corresponding members of the source character set or by escape sequences consisting of the backslash \ followed by one or more characters. A byte with all bits set to 0, called the null character, shall exist in the basic execution character set; it is used to terminate a character string.

和(7.21.6.1 fprintf函数)

8 The conversion specifiers and their meanings are:

s If no l length modifier is present, the argument shall be a pointer to the initial element of an array of character type.273) Characters from the array are written up to (but not including) the terminating null character.

我的编译器(GCC)说:

warning: ‘__builtin_memcpy’ writing 12 bytes into a region of size 8 overflows the destination [-Wstringop-overflow=] strcpy(string_two, "Long string");

并且只是为了展示优化将如何利用你认为你知道的一切并将其颠倒过来,如果你在 64 位 PowerPC Power 上编译它会发生什么-9(又名不是 x86)与 gcc -O3 -flto

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

因为如果您查看机器代码,它根本不会执行 strcpy