程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++的引用類型的變量到底占不占用內存空間?,變量占用內存

C++的引用類型的變量到底占不占用內存空間?,變量占用內存

編輯:C++入門知識

C++的引用類型的變量到底占不占用內存空間?,變量占用內存


——by  karottc

分析一下 C++ 裡面的引用類型(例如: int &r = a;  )中的 r 變量是否占用內存空間呢?是否和  int *p = &a;  中的 p 變量一樣占用內存空間呢?

本文將給出答案。

直接看一個簡單的例子:

#include <iostream>

using namespace std;

int main(void)
{
    int a = 6;
    int &r = a;
    int *p = &a;
    int x = r;
    return 0;
}

 

接著我們通過  g++ testref.cpp -o testref -g  來編譯之後,用gdb來加載它,看看 arpx 的地址分別是多少:

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

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

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

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

00000000004006cd <main>:
  4006cd:   55                      push   %rbp
  4006ce:   48 89 e5                mov    %rsp,%rbp
  4006d1:   c7 45 e8 06 00 00 00    movl   $0x6,-0x18(%rbp)   # int a = 6; a的地址 0x18
  4006d8:   48 8d 45 e8             lea    -0x18(%rbp),%rax
  4006dc:   48 89 45 f0             mov    %rax,-0x10(%rbp)   # int &r = a; r的地址 0x10
  4006e0:   48 8d 45 e8             lea    -0x18(%rbp),%rax
  4006e4:   48 89 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:   89 45 ec                mov    %eax,-0x14(%rbp)   # int x = r;   x的地址 0x14
  4006f1:   b8 00 00 00 00          mov    $0x0,%eax
  4006f6:   5d                      pop    %rbp
  4006f7:   c3                      retq 

 

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

所以,現在可以得到結論:引用類型的變量會占用內存空間,占用的內存空間的大小和指針類型的大小是相同的。 從上面的匯編代碼可以看出,雖然引用是一個對象的別名,但是在匯編層面,和指針是一樣的。

 

【本文首發於:http://www.karottc.com/blog/2015/07/29/cpp-reference/】

2015.07.29

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved