※ 引述《kdok123 (小天)》之銘言:
: 對不起問題有點混亂了,其實只是想知道pointer和reference後面到底是怎麼運作的
: EX:
假設是在 64-bit 的環境,sizof(void*)=8, sizeof(int)=8
: int a[] = {1,2,3,4,5};
: int *k = a;
: int **k2 = &k;
: int ***k3 = &k2;
: cout<< k << ' ' << a << ' ' << endl;//此時k和a是相同的位址
: cout << *(*(&a+1)-1) << endl; //輸出5
例
a 的位置是 0x10000000,64-bit int,所以佔8格至 0x10000007
a[1] 的位置是 0x10000008 (至 0x1000000F)
a[2] 的位置是 0x10000010
a[4] 的位置是 0x10000020 (至 0x10000027)
因為你用了 int a[]={...} 的宣告,所以 a 的 type 是 int[5]
所以 &a 是一個(int[5])*,它的運算是以 int[5] 為準,也就是說
*(&a+1) 是個int[5],指向的是 a[0] 後的第5個int
*(&a+1)-1 是個int ,指向的是 a[0] 後的第4個int,即 a[4]
所以 *(*(&a+1)-1)=a[4]=5
: cout << *(*(&k+1)-1) << endl; //這個地方是印不出來的,錯誤是未初始化變數k
例(續)
k 的位置假設是 0x20000000 至 0x20000007
k 只是一個int* (不是int[5]喔),所以 &k+1 指向的是k後面的一個int*,即位置
0x20000008 至 0x2000000F (把這 8-byte 解讀成 int*)
但問題來了,這個位置不一定是你的!所以 *(&k+1) 就會亮起警報:
這程式不會是想偷什麼資料吧?
所以之後的運算也作不下去了
: 我的認知這裡應該也要輸出5
: 不知道觀念哪裡有問題了呢?
有兩個明顯問題:
1. k 和 a 只是指向的位置相同,它們本身的位置並不同
2. 就算本身位置相同,他們指向的 type 也不相同,運算也會不同
: (會想這個例子是因為想知道*(&k+1),**(&k2+1)到底會前進幾個int,
: 只是在第一步就卡住了)
不會前進幾個int,因為本不該你看到,如果看到的話是系統安全漏洞!(像
幾個月前 Heartbleed 這樣的問題)