请考虑以下代码:
char str1[] = "Hello";
char str2[] = "Hello\0\0\0l\0o";
int x;
x=memcmp(str1,str2,sizeof(str2));
printf("%d",x);
当我运行它时,它显示o / p为:
1
你能解释一下这个的原因吗?我了解到两个字符串中的每个字节都进行了比较并相应地返回。但我不清楚最后会发生什么。
答案 0 :(得分:6)
您的程序调用未定义的行为。
sizeof(str2)
大于sizeof(str1)
。通过使用它作为memcmp
的最后一个参数,您正在访问您不应该访问的内存。这是未定义行为的原因。
因此,输出可以是任何东西。尝试理解它是毫无意义的。
答案 1 :(得分:3)
进行字符串比较时,一旦达到'\ 0',它将停止比较。在这里你已经完成了一个memcmp,在读取所有请求的字符之前不会停止。
在这种情况下,你要比较sizeof(str2)字节,在str1的情况下,在结尾隐含的'\ 0'之后会产生垃圾。
在比较中获得0:
答案 2 :(得分:1)
请记住,此处调用memcmp
不安全,有时危险,因为str1的长度少于str2。
请考虑以下代码:
int main()
{
char str1[] = "Hello";
char str2[] = "AAAAA\0\0\0l\0o";
for(int i=0; i<sizeof(str2); i++)
printf("%02X %02X\n", str1[i], str2[i]);
printf("\n%X %X", (int)str1, (int)str2);
return 0;
}
输出
48 41
65 41
6C 41
6C 41
6F 41
00 00
41 00
41 00
41 6C
41 00
41 6F
00 00
28FEEE 28FEF4
我们可以看到str1
的[6] - [11]字节实际上是str2
的第一个字节,可以通过str1
和{{的地址确认1}}。在这种情况下,GCC / MSVC(我对Clang不太确定)连续存储两个字符串const初始化器。因此,当您在空终止符str2
之后调用memcmp
时,该函数实际上会将\0
的第一个字节与str2
进行比较。
但请记住,编译器存储常量的方式可能会在任何情况下发生变化。你应该不依赖这种行为。