0

我一直在做一个项目,我花了最后一个小时试图在我的代码中找到错误。仔细检查后,我注意到一些相当奇怪的问题,这一直是问题所在。

我的数组的初始元素的地址奇怪地比较等于memcmp()。我已经分离了我的代码并尝试了一个测试代码,我得到了类似的结果。有人可以解释这种奇怪的行为吗?

#include <stdio.h>
#include <string.h>

int main(void)
{
    char buf[256];

    char *p1 = buf;
    char *p2 = buf + 3;

    if (memcmp(p1, p2, sizeof(char *)) == 0) {
        puts("equal...");
    }

    p1 = buf + 100;
    p2 = p1  + 3; 

    if (memcmp(p1, p2, sizeof(char *)) == 0) {
        puts("equal...");
    }
    return 0;
}
4

5 回答 5

2

你有未定义的行为

局部变量,无论是简单的整数还是数组,都不会被初始化。它们的价值是不确定的。在初始化导致未定义行为之前以任何方式使用它们,甚至从它们中读取。

此外,您不是在比较两个字符,而是一次比较 4 个或 8 个字符,具体取决于您使用的是 32 位还是 64 位系统。如果要比较应使用的单个字符sizeof(char)(指定为始终等于1)。您也不是在比较指针,而是在比较它们指向的内容。

如果要比较两个单个字符,请改用 compare-equal 运算符==,例如 eg*p1 == *p2或 plainly buf[0] == buf[3]

于 2016-07-23T07:25:35.710 回答
1

memcmp不比较地址。它比较内存。

int memcmp(const void *s1, const void *s2, size_t n);

memcmp比较 和 的第一个n字节,s1s2它们是否相等。

在这里,你有

if (memcmp(p1, p2, sizeof(char *)) == 0) {

sizeof(char *)将是您的指针大小,可能是 4 或 8,具体取决于您的架构。

这意味着您正在比较sizeof(char *)p1 和 p2 的第一个字节是否相等。由于您从未初始化此数据,因此发生的事情几乎是随机的。我假设您的实际代码将它归零,这很容易解释为什么它总是比较相等。

于 2016-07-23T07:26:09.523 回答
0

在调试器中运行代码并检查 buf 的内容是什么。一些编译器在调试模式下将数组中的所有项目归零,并在发布版本中为它们提供不确定的值。或者在发布版本中运行代码并检查它们是否仍然相等

于 2016-07-23T07:26:27.283 回答
0

我认为memcmp()比较内存中存在的内容而不是您传递的指针。如果要比较指针(地址),请将指向指针的指针和大小传递为 sizeof(1)

因此为您的问题修改了代码

/* to compare addresses */
/* simple one */
if(p1 == p2)

/* redundant one */
if(!memcmp(&p1, &p2, sizeof(p1))
于 2016-07-23T07:27:17.827 回答
0

您正在尝试比较指针变量的 4 字节内容p1p2. 但是您实际上是在比较 4 个字节p1p2指向的,因为这就是这样memcmp做的。

前两个参数memcmp是您要查看的数据的内存地址,变量的内存地址通过&在变量之前使用运算符指示。

你要

memcmp(&p1, &p2, sizeof(char*));
于 2016-07-23T07:33:38.383 回答