zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    JQuery性能优化
    分页控件X.PagedList.Mvc
    《转》sql 、linq、lambda 查询语句的区别
    Linq的连表查询
    MVC页面直接F5出错
    详解集合
    Json的序列化与反序列化
    《转》dbcontext函数
    《转》jquery中的$.ajax的success与error
    cocos creator基础-(二十七)httpclient Get POST
  • 原文地址:https://www.cnblogs.com/karottc/p/cpp-reference.html
Copyright © 2011-2022 走看看