为什么这两个指针相减会得到不同的结果

Why do these two pointer subtractions give different results?

本文关键字:结果 相减 指针 两个 为什么      更新时间:2023-10-16

考虑以下代码:

char* p = new char[2];
long* pi = (long*) p;
assert(p == pi);         // OK
char* p1 = &p[1];
long* pi1 = (long*) p1;
assert(p1 == pi1);       // OK
int d = p1 - p;
int d1 = pi1 - pi;
assert(d == d1);         // No :(

运行之后,我得到了d == 1d1 == 0,尽管p1 == pi1p == pi(我在调试器中检查了这一点)。这是未定义的行为吗?

正如其他人所指出的,这是未定义的行为。然而,对于你所看到的,有一个非常简单的解释。

指针之间的区别在于元素的数量,而不是它们之间的字节数。

pi和pi1都指向long,但pi1指向的地址只比pi多一个字节。假定长为4字节长,则地址1除以元素大小4的差值为0。

另一种思考方式是,你可以想象编译器会生成与此等效的代码来计算d1:

int d1 = ((BYTE*)pi1 - (BYTE*)pi)/sizeof(long).

如果指针不指向同一个数组,或者指针是从指针类型转换为不相关的类型,则两个指针之间的差异是未定义的。

此外,差异不在于字节,而在于元素的数量。

在第二种情况下,差值是1个字节,但它被sizeof(long)除。注意,因为这是未定义的行为,所以这里的任何答案都是正确的。

重新解释指针的基本类型不会更改其地址。但是指针算法会根据指针类型产生不同的结果。所以你在这里描述的是完全正确的,这也是我所期望的。请参阅指针算术。

它为pi1 - pi做整数(长)指针运算;

如果p1&p[4],您会看到它为d1打印1,而差异实际上是4个字节。这是因为sizeof (long)=4个字节。