c++引用深入分析

幾天前寫過關於引用和指針的區別,當時心裏就有一個疑惑,既然都說引用是對象的一個別名,那引用變量到底有沒有被分配存儲空間。我去Google了一下,發現網上有兩種截然不同的看法,一種說是在棧裏分配了空間,另一種則是說沒有分配空間,僅僅是別名而已。經過幾天的看書以及思考,我又有了新的體會,特寫此篇。同時也感謝博文《c++引用深入探討》給我的靈感
http://www.cnblogs.com/winter-cn/archive/2010/07/15/1777668.html


引用分配了棧空間

要想證明這一點,很自然的就想到了通過使用(void*)函數或是&取址符號來獲得,遺憾的是無論哪一種方式返回的都是被引用對象的地址。那麼引用變量地址是不是就是被引用的被引用對象的地址呢?
換一種思路,如果引用變量被分配了棧空間,那麼很明顯這會引起周圍其他變量地址的偏移。如果能夠找到這樣的偏移,也間接地證明了引用變量被分配了棧空間。

void fa(){
    int a[4];    
    cout<<a<<endl;
}
void fb(){
    int a[4];
    //int &b=a[0];
    //註釋掉後,fb內存空間會變小
    cout<<a<<endl;
    fa();
}
void fc(){
    int a[4];
    cout<<a<<endl;
    fb();
}

定義了三個函數,分別是fa(),fb(),fc(),其中fb()被其他兩個函數夾在中間。我們通過輸出函數的地址,知道每個函數被分配的空間大小。在VS2012,win8.1 32位系統下,發現在註釋掉下面這行代碼後,

int &b=a[0];

函數空間少了近12字節,注意這個12字節,有沒有感覺很奇怪,int型數據不是4字節嗎,怎麼多出了8字節?這有待我以後慢慢思索。


確定引用變量地址

雖然證明了引用變量也會被分配空間,但是沒找到具體的地址空間還是缺少說服力,難以令人信服。
我們知道在c++中是不會對數組進行越界處理的,在數組下標越界時,通常情況下系統是不會報錯,而是直接讀取當前地址的值,通常是未知的,因此在碼代碼時要十分注意數組邊界的問題。然而這次要利用C++的這個性質爲我們服務。先上代碼片段

int a = -1;
int b[4] = {0,1,2,3};
int c = 4;
cout<<&a<<endl;
cout<<b<<"\t"<<b[0]<<endl<<&b[1]<<"\t"<<b[1]<<endl<<&b[2]<<"\t"<<b[2]<<endl<<&b[3]<<"\t"<<b[3]<<endl;
cout<<&c<<endl;
cout<<b[-3]<<endl<<b[6]<<endl;

運行結果如下
我們可以發現:

  1. 分配內存時,是從高位地址開始往低位地址分配的;
  2. 數組分配內存時,低位地址分配低下標數據,高位地址分配高下標數據。這裏的高位地址不是形如高8位的意思。
  3. 雖然a和b數組是順序聲明的,但是之間隔着12個字節,多出了的8字節是什麼呢!

接下來就是把上面的int型變量變成引用的過程了。

    int ri = -1;
    int ra[4] = {0,1,2,3};
    int &c = ri;
    int b = 2;
    //c引用ri,且地址爲ra[-3]
    cout<<ra[-3]<<endl;
    cout<<ra[-6]<<endl;
    cout<<"修改ra[-3],使其指向ra[1]"<<endl;
    ra[-3] = ra[1];
    cout<<"修改ra[-3]後,ri值爲:"<<ri<<endl;
    ri = -100;
    cout<<"修改原引用ri後,ra[-3]值爲:"<<ra[-3]<<endl;
    ra[1] = 100;
    cout<<"繼續修改ra[1]後,ra[-3]的值爲:"<<ra[-3]<<endl;

這裏寫圖片描述
輸出的3537468即代表當前引用變量地址裏存的數據,之所以加上b=2是爲了確信ra[-3]裏存放的就是引用變量。後面的對ra[-3]的一系列操作是爲了確認能否通過修改引用變量地址存放的數據來修改對引用變量的重綁定操作。很遺憾,答案是否定的。


新的問題

到目前爲止,我基本已經搞清了引用變量的地址以及大小,然而新的問題又湧現了出來。
1. 引用變量或是原對象的一些修改操作是如何實時地反映到原對象或是引用變量上的。
2. 如上面所示,輸出的3537468代表了什麼意思,很確信這不是一個地址,因爲原對象地址與這個不同。
3. 之前提到的12字節問題,多出來的8字節到底是什麼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章