使用c中的memcmp比较两个字符串

时间:2016-06-13 05:56:36

标签: c

请考虑以下代码:

char str1[] = "Hello";
char str2[] = "Hello\0\0\0l\0o";
int x;
x=memcmp(str1,str2,sizeof(str2));
printf("%d",x);

当我运行它时,它显示o / p为:

1

你能解释一下这个的原因吗?我了解到两个字符串中的每个字节都进行了比较并相应地返回。但我不清楚最后会发生什么。

3 个答案:

答案 0 :(得分:6)

您的程序调用未定义的行为。

sizeof(str2)大于sizeof(str1)。通过使用它作为memcmp的最后一个参数,您正在访问您不应该访问的内存。这是未定义行为的原因。

因此,输出可以是任何东西。尝试理解它是毫无意义的。

答案 1 :(得分:3)

进行字符串比较时,一旦达到'\ 0',它将停止比较。在这里你已经完成了一个memcmp,在读取所有请求的字符之前不会停止。

在这种情况下,你要比较sizeof(str2)字节,在str1的情况下,在结尾隐含的'\ 0'之后会产生垃圾。

在比较中获得0:

  • 仅比较sizeof(str1)或sizeof(str1)+1 bytes
  • 做一个字符串比较

答案 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进行比较。 但请记住,编译器存储常量的方式可能会在任何情况下发生变化。你应该依赖这种行为。