[英]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
(我在調試器中檢查了這一點)。 這是未定義的行為嗎?
正如其他人指出的那樣,這是未定義的行為。 但是,對於您所看到的內容,有一個非常簡單的解釋。
指針之間的區別是元素的數量,而不是它們之間的字節數。
pi和pi1都指向long,但是pi1指向的地址只比pi大一個字節。 假設long為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個字節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.