C++的引用类型的变量到底占不占用内存空间?
——by karottc
分析一下 C++ 里面的引用类型(例如: int &r = a; )中的 r
变量是否占用内存空间呢?是否和 int *p = &a; 中的 p
变量一样占用内存空间呢?
本文将给出答案。
直接看一个简单的例子:
#include <iostream> using namespace std; int main(void)
{
int a = ;
int &r = a;
int *p = &a;
int x = r;
return ;
}
接着我们通过 g++ testref.cpp -o testref -g 来编译之后,用gdb来加载它,看看 a
, r
, p
, x
的地址分别是多少:
上图中 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: push %rbp
4006ce: e5 mov %rsp,%rbp
4006d1: c7 e8 movl $0x6,-0x18(%rbp) # int a = ; a的地址 0x18
4006d8: 8d e8 lea -0x18(%rbp),%rax
4006dc: f0 mov %rax,-0x10(%rbp) # int &r = a; r的地址 0x10
4006e0: 8d e8 lea -0x18(%rbp),%rax
4006e4: f8 mov %rax,-0x8(%rbp) # int *p = &a; p的地址 0x8
4006e8: 8b f0 mov -0x10(%rbp),%rax # 下面两行是为了后面的赋值做准备
4006ec: 8b mov (%rax),%eax
4006ee: ec mov %eax,-0x14(%rbp) # int x = r; x的地址 0x14
4006f1: b8 mov $0x0,%eax
4006f6: 5d pop %rbp
4006f7: c3 retq
我把对应处,都写在上面的注释里了。
所以,现在可以得到结论:引用类型的变量会占用内存空间,占用的内存空间的大小和指针类型的大小是相同的。 从上面的汇编代码可以看出,虽然引用是一个对象的别名,但是在汇编层面,和指针是一样的。
【本文首发于:http://www.karottc.com/blog/2015/07/29/cpp-reference/】
2015.07.29
C++的引用类型的变量到底占不占用内存空间?的更多相关文章
- C语言中计算变量占用内存空间
C语言中计算变量占用内存空间 在C语言中通常用[sizeof]运算符计算变量占内存空间,如下面的例子:
- 一个Java对象到底占多大内存
最近在读<深入理解Java虚拟机>,对Java对象的内存布局有了进一步的认识,于是脑子里自然而然就有一个很普通的问题,就是一个Java对象到底占用多大内存? 在网上搜到了一篇博客讲的非常好 ...
- 一个Java对象到底占多大内存?(转)
最近在读<深入理解Java虚拟机>,对Java对象的内存布局有了进一步的认识,于是脑子里自然而然就有一个很普通的问题,就是一个Java对象到底占用多大内存? 在网上搜到了一篇博客讲的非常好 ...
- 【转】一个Java对象到底占多大内存?
最近在读<深入理解Java虚拟机>,对Java对象的内存布局有了进一步的认识,于是脑子里自然而然就有一个很普通的问题,就是一个Java对象到底占用多大内存? 在网上搜到了一篇博客讲的非常好 ...
- Visual Studio 2017 如何 监控当前变量 占用内存空间大小
在进行VS调试时 大家是否想知道当前变量 占用了内存多少空间呢 这对系统调优还是很有帮助的吧
- C++中class在实例化前到底占用多少空间
最近忽然想起一个问题,C++中class在实例化前到底占用多少空间?我隐约记得书上是这么说的“类在实例化时才分配空间”!但是当我写下这个小程序的时候,杯具产生了—— #include<iostr ...
- Java中的String到底占用多大的内存空间?你所了解的可能都是错误的!!
写在前面 最近小伙伴加群时,我总是问一个问题:Java中的String类占用多大的内存空间?很多小伙伴的回答着实让我哭笑不得,有说不占空间的,有说1个字节的,有说2个字节的,有说3个字节的,有说不知道 ...
- C++中的类所占内存空间总结
C++中的类所占内存空间总结 最近在复习c++的一些基础,感觉这篇文章很不错,转载来,大家看看! 类所占内存的大小是由成员变量(静态变量除外)决定的,成员函数(这是笼统的说,后面会细说)是不计算 ...
- C++中的类所占内存空间总结(转)
类所占内存的大小是由成员变量(静态变量除外)决定的,成员函数(这是笼统的说,后面会细说)是不计算在内的. 摘抄部分: 成员函数还是以一般的函数一样的存在.a.fun()是通过fun(a.this)来调 ...
随机推荐
- GitHub的使用 —— 如何删除Repository
如果要在GitHub上删除一个已经存在的Repository,该怎么办呢 ? 1.首先,点击这个资源(Repository),进入.会看到如下页面: 2.点击 Admin .在 Admin 页面的最下 ...
- linux系统的权限介绍
让我们用t o u c h命令创建一个文件:$ touch myfile现在对该目录使用ls -l命令: 我们已经创建了一个空文件,正如我们所希望的那样,第一个横杠告诉我们该文件是一个普通文件.你将会 ...
- 在服务器端保存ViewState
1.比较 Asp.net 的一个强大的功能就是ViewState, 但是这也成为很多人诟病的地方,我们先来看一个实例 ViewState其中一个特性就是保存页面的状态,下面我们看一个很简单的登录页面 ...
- URAL1091. Tmutarakan Exams(容斥)
1091 容斥原理 #include <iostream> #include<cstdio> #include<cstring> #include<algor ...
- cut命令如何截取以空格隔开的字段
你的文件分隔符恐怕不止一个空格(一定的who生成的): 用awk: awk '{print $2}' file 一定要用cut的话: cat file|tr -s ' '|cut -d' ' -f2 ...
- 博客已搬家至 hate13.com
博客园停止更新,新博客链接:hate13.com 欢迎访问~
- maven打包无法打包mybatis及系统配置文件问题
<resources> <!-- mybatis映射文件 --> <resource> <directory>src/main/java/com/bsh ...
- 【C#学习笔记】保存文件
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- dede栏目调用大全
A:侧边栏常用的当前栏目的父栏目调用(5.7) 1.在include/common.inc.php增加函数 function getTopCategoryName($cid=0) { global $ ...
- poj2387 Til the Cows Come Home
解题思路:最短路的模板题,注意一个细节处理即可. 见代码: #include<cstdio> #include<cstring> #include<algorithm&g ...