C 的引用型別的變數到底佔不占用記憶體空間?

2021-07-23 06:04:24 字數 2934 閱讀 6245

分析一下 c++ 裡面的引用型別(例如: int &r = a;  )中的r變數是否占用記憶體空間呢?是否和  int *p = &a;  中的p變數一樣占用記憶體空間呢?

本文將給出答案。

直接看乙個簡單的例子:

#include using

namespace

std;

int main(void

)

接著我們通過  g++ testref.cpp -o testref -g

來編譯之後,用gdb來載入它,看看a,r,p,x的位址分別是多少:

id="iframe_0.7060913229361176" src="data:text/html;charset=utf8,%3cimg%20id=%22img%22%20src=%22'img');%20window.parent.postmessage(%7biframeid:'iframe_0.7060913229361176',width:img.width,height:img.height%7d,%20'');%7d%3c/script%3e" frameborder="0" scrolling="no" style="margin: 0px; padding: 0px; border-style: none; border-width: initial; width: 411px; height: 293px;">

上圖中a的位址為0x7fffffffe208,用取位址符去獲取r位址,值和a是一樣的,其實,用&符號是不能獲取到引用型別變數的位址的,因為引用型別的變數本身只是另乙個物件的別名,用可感知的方式描述,就是它僅僅是乙個名字而已,對它的任何操作都是相當於對另乙個物件的操作,所以這個取位址操作也是一樣。

但是,我們接著往下看,p的位址是0x7fffffffe218,和a的位址剛剛相差了 16 位元組,接著看x的位址是0x7fffffffe20c,這個位址正好是a的位址0x7fffffffe208 + 4, 而aint型,變數本身占用 4 位元組,正常情況下,x的位址應該是p的位址0x7fffffffe218 + 8,這裡+8是因為我的機器是 64 位的機器,所以指標型別占用 8 位元組。現在這種情況應該是編譯器做了優化,把x的放到了a的後面,同樣的,x的下乙個變數的起始位址應該是0x7fffffffe20c + 4=0x7fffffffe210,這個位址和p之間剛好差了 8 個位元組,也就是乙個指標變數的位址,所以答案就很明顯了。

即,我們現在可以猜測,r是占用記憶體空間,並且占用的大小和指標變數相同大小。但是我們上面用gdb也看不了r的實際位址,所以這也只能是猜測,只是看似合理的猜測而已。

為了證明這個猜測,我們繼續把可執行檔案反彙編出來看看:objdump -d testref得到的結果如下:

00000000004006cd :

4006cd:

55 push %rbp

4006ce:

4889 e5 mov %rsp,%rbp

4006d1: c7

45 e8 06

0000

00 movl $0x6,-0x18(%rbp) # int a = 6; a的位址 0x18

4006d8:

48 8d 45 e8 lea -0x18(%rbp),%rax

4006dc:

4889

45 f0 mov %rax,-0x10(%rbp) # int &r = a; r的位址 0x10

4006e0:

48 8d 45 e8 lea -0x18(%rbp),%rax

4006e4:

4889

45 f8 mov %rax,-0x8(%rbp) # int *p = &a; p的位址 0x8

4006e8:

48 8b 45 f0 mov -0x10(%rbp),%rax # 下面兩行是為了後面的賦值做準備

4006ec: 8b

00 mov (%rax),%eax

4006ee:

8945 ec mov %eax,-0x14(%rbp) # int x = r; x的位址 0x14

4006f1: b8

0000

0000 mov $0x0,%eax

4006f6: 5d pop %rbp

4006f7: c3 retq

我把對應處,都寫在上面的注釋裡了。

所以,現在可以得到結論:引用型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。 從上面的彙編**可以看出,雖然引用是乙個物件的別名,但是在彙編層面,和指標是一樣的。

【本文首發於:

C語言中結構體變數到底占多大空間

很久之前就想將記憶體對齊這塊兒知識點總結記錄下來,無奈本人患有very very嚴重的拖拉症,直到今天才下決心將這件事兒解決掉,廢話不多說了,開工!ps 本人所用編譯器version為 gcc ubuntu4.9.2 10 ubuntu13 4.9.2 結構體到底占多大的空間呢?先看一下下面這道題的...

C語言中結構體變數到底占多大空間

很久之前就想將記憶體對齊這塊兒知識點總結記錄下來,無奈本人患有very very嚴重的拖拉症,直到今天才下決心將這件事兒解決掉,廢話不多說了,開工!ps 本人所用編譯器version為 gcc ubuntu4.9.2 10 ubuntu13 4.9.2 結構體到底占多大的空間呢?先看一下下面這道題的...

傳遞引用變數到thread的方法

為了加速執行乙個c 程式,我們常常會用到multiple thread程式設計。比如下面是乙個例子 include include void message std string msg std coutint main std string msg love the world std threa...