为什么初始数组元素的地址比较相等?
Why do the addresses of initial array elements compare equal?
我一直在做一个项目,我花了最后一个小时试图找到我的代码中的错误。经过仔细检查,我发现了一些很奇怪的问题,这一直是问题所在。
我的数组初始元素的地址奇怪地与 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 个或 8 个字符,具体取决于您使用的是 32 位系统还是 64 位系统。如果你想比较单个字符,你应该使用 sizeof(char)
(指定总是等于 1
)。您也不是在比较指针,而是在比较它们指向的内容。
如果您想比较两个单个字符,请改用比较等于运算符 ==
,例如*p1 == *p2
或直接 buf[0] == buf[3]
.
memcmp
不比较地址。它比较内存。
int memcmp(const void *s1, const void *s2, size_t n);
memcmp
比较 s1
和 s2
的前 n
个字节,看它们是否相等。
在这里,你有
if (memcmp(p1, p2, sizeof(char *)) == 0) {
sizeof(char *)
将是您的指针大小,可能是 4 或 8,具体取决于您的架构。
这意味着您正在比较 p1 和 p2 的前 sizeof(char *)
个字节是否相等。由于您从未初始化此数据,因此发生的事情几乎是随机的。我假设您的实际代码将其归零,这很容易解释为什么它总是比较相等。
运行 调试器中的代码并检查 buf 的内容是什么。
一些编译器在调试模式下将数组中的所有项目置零,并在发布版本中为它们提供不确定的值。
或 运行 发布版本中的代码并检查它们是否仍然相等
我认为 memcmp()
比较内存中存在的内容 而不是 您传递的指针。如果你想比较指针(地址)将指针传递给指针和大小为 sizeof(1)
因此修改了您问题的代码
/* to compare addresses */
/* simple one */
if(p1 == p2)
/* redundant one */
if(!memcmp(&p1, &p2, sizeof(p1))
您正在尝试比较指针变量 p1
和 p2
的 4 字节内容。但是您实际上是在比较 p1
和 p2
指向的 4 个字节,因为那是 memcmp
所做的。
memcmp
的前两个参数是要查看的数据的内存地址,变量的内存地址用变量前的&
运算符表示。
你想要
memcmp(&p1, &p2, sizeof(char*));
我一直在做一个项目,我花了最后一个小时试图找到我的代码中的错误。经过仔细检查,我发现了一些很奇怪的问题,这一直是问题所在。
我的数组初始元素的地址奇怪地与 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 个或 8 个字符,具体取决于您使用的是 32 位系统还是 64 位系统。如果你想比较单个字符,你应该使用 sizeof(char)
(指定总是等于 1
)。您也不是在比较指针,而是在比较它们指向的内容。
如果您想比较两个单个字符,请改用比较等于运算符 ==
,例如*p1 == *p2
或直接 buf[0] == buf[3]
.
memcmp
不比较地址。它比较内存。
int memcmp(const void *s1, const void *s2, size_t n);
memcmp
比较 s1
和 s2
的前 n
个字节,看它们是否相等。
在这里,你有
if (memcmp(p1, p2, sizeof(char *)) == 0) {
sizeof(char *)
将是您的指针大小,可能是 4 或 8,具体取决于您的架构。
这意味着您正在比较 p1 和 p2 的前 sizeof(char *)
个字节是否相等。由于您从未初始化此数据,因此发生的事情几乎是随机的。我假设您的实际代码将其归零,这很容易解释为什么它总是比较相等。
运行 调试器中的代码并检查 buf 的内容是什么。 一些编译器在调试模式下将数组中的所有项目置零,并在发布版本中为它们提供不确定的值。 或 运行 发布版本中的代码并检查它们是否仍然相等
我认为 memcmp()
比较内存中存在的内容 而不是 您传递的指针。如果你想比较指针(地址)将指针传递给指针和大小为 sizeof(1)
因此修改了您问题的代码
/* to compare addresses */
/* simple one */
if(p1 == p2)
/* redundant one */
if(!memcmp(&p1, &p2, sizeof(p1))
您正在尝试比较指针变量 p1
和 p2
的 4 字节内容。但是您实际上是在比较 p1
和 p2
指向的 4 个字节,因为那是 memcmp
所做的。
memcmp
的前两个参数是要查看的数据的内存地址,变量的内存地址用变量前的&
运算符表示。
你想要
memcmp(&p1, &p2, sizeof(char*));