请考虑以下代码:
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 :(
Run Code Online (Sandbox Code Playgroud)
在此之后跑,我得d == 1
和d1 == 0
,虽然p1 == pi1
和p == pi
(我在调试器中检查这一点).这是未定义的行为吗?
Mic*_*ael 10
正如其他人指出的那样,这是未定义的行为.但是,对于您所看到的内容,有一个非常简单的解释.
指针之间的区别是元素的数量,而不是它们之间的字节数.
pi和pi1都指向long,但是pi1指向的地址只比pi大一个字节.假设long为4个字节长,地址的差值1除以元素4的大小为0.
另一种思考方式是你可以想象编译器会生成与此相当的代码来计算d1:
int d1 = ((BYTE*)pi1 - (BYTE*)pi)/sizeof(long).
Run Code Online (Sandbox Code Playgroud)
如果指针不指向同一个数组,或者指针是从指向不相关类型的指针进行类型转换,则两个指针之间的差异是未定义的.
此外,差异不是以字节为单位,而是以元素数量表示.
在第二种情况下,差异是1个字节,但它除以sizeof(long).请注意,因为这是未定义的行为,所以这里的任何答案都是正确的.
归档时间: |
|
查看次数: |
428 次 |
最近记录: |