提问人:Luchian Grigore 提问时间:2/8/2012 最后编辑:Russell BorogoveLuchian Grigore 更新时间:2/8/2012 访问量:449
为什么这两个指针减法给出不同的结果?
Why do these two pointer subtractions give different results?
问:
请考虑以下代码:
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 == 1
d1 == 0
p1 == pi1
p == pi
答:
5赞
Mark Ransom
2/8/2012
#1
如果指针不指向同一数组,或者指针是从指向不相关类型的指针类型转换的,则两个指针之间的差异是未定义的。
此外,区别不在于字节,而在于元素的数量。
在第二种情况下,差值是 1 个字节,但它被除以 sizeof(long)。请注意,由于这是未定义的行为,因此此处的任何答案都绝对是正确的。
评论
0赞
2/8/2012
伙计,我看着你的头像笑了:)这是一个绝妙的主意:)))
2赞
Seth Carnegie
2/8/2012
在哪个部分中,您不能对从不相关类型转换的指针进行指针算术运算
0赞
Mark Ransom
2/8/2012
@SethCarnegie,我不能指出任何具体的东西,事实上我可能弄错了。我认为类型转换本身生成了 UB,尤其是在这种情况下,因为它与类型未对齐。
0赞
Seth Carnegie
2/8/2012
啊,你是对的。(对于任何想知道的人,我认为这在§5.2.10.7中都有详细说明)
2赞
user405725
2/8/2012
#2
重新解释指针的基础类型不会更改其地址。但是指针算术会根据指针类型产生不同的结果。所以你在这里描述的是完全正确的,这就是我所期望的。请参阅指针算术。
0赞
jman
2/8/2012
#3
它做整数(长)指针算术pi1 - pi
;
如果是这样,你会看到它打印了,而差异实际上是 4 个字节。这是因为 = 4 个字节。p1
&p[4]
1
d1
sizeof (long)
评论
0赞
Grizzly
2/8/2012
的大小取决于平台,因此差异可能是即使指向(或者可能是或其他东西)。事实上,许多 64 位平台都有 8byte .IIRC 甚至存在平台,其中 ( 例如 在那些)long
0
p1
&p[4]
4
long
sizeof(long)==1
char
64bit
10赞
Michael
2/8/2012
#4
正如其他人所指出的,这是未定义的行为。但是,对于您所看到的内容,有一个非常简单的解释。
指针之间的区别在于元素的数量,而不是它们之间的字节数。
pi 和 pi1 都指向 longs,但 pi1 指向的地址只比 pi 多一个字节。假设 long 的长度为 4 个字节,则地址的差值 1 除以元素的大小 4 为 0。
另一种思考方式是,您可以想象编译器将生成与此等效的代码来计算 d1:
int d1 = ((BYTE*)pi1 - (BYTE*)pi)/sizeof(long).
评论
pi1 - pi
sizeof(long)