Sizeof的计算看内存分配
本文记录了有关sizeof的一些计算,主要有下面的四种情况:(如有错误,敬请留言)
- 使用sizeof()计算普通变量所占用的内存空间
- sizeof计算类对象所占用空间的大小-用到了字节对齐
- sixeof计算含有虚函数的类对象的空间大小
- sizeof计算虚拟继承的类对象的空间大小
使用sizeof()计算普通变量所占用的内存空间
#include <iostream>
#include <stdlib.h>
using namespace std; //如果数组变量被传入函数中做sizeof()运算,则和指针的运算没有区别。
void Func( char str[] )
{
cout<<"Fun: == "<<sizeof(str)<<endl;//4字节的指针
} int main()
{
char str[] = "Hello";
char *p = str;
int n = ; cout<<"str == "<<sizeof(str)<<endl;
//结果=6=strlen("Hello")+1;数值中要留一个元素保存字符串结束符
Func(str); //2个结果都是4,win32下,指针和int都是4字节
cout << "p ==" << sizeof(p) << endl;
cout << "n ==" << sizeof(n) << endl;//结果4 void *q = malloc();//100字节的堆内存
cout << "void * == " << sizeof(q) << endl;
//还是4(指针类型的大小) char *ch = (char *)malloc(sizeof(char)*);
cout << "char * == " <<sizeof(ch) << endl;
//还是4(指针类型的大小) return ;
}
//数组和指针的sizeof()是有区别的。
//对于指针,不论何种类型,其大小都是4字节的。
通过上面的示例,我们可以看到:sizeof计算的都是数据类型占用空间的大小,除了一种情况,就是初始化char str[]="Hello"的时候,sizeof计算的是字符串的长度+1.
sizeof计算类对象所占用空间的大小-用到了字节对齐
#include <iostream>
using namespace std; class A
{
public:
int i;//
};
class AA
{
public:
double d;
int i;//8+4+4(补全)
};
class B
{
public:
char ch;//
};
class C
{
public:
int i;
short j;//4+2+2(补全)
};
class D
{
public:
int i;
short j;
char ch;//4+2+1+1(补全)
};
class E
{
public:
int i;
int ii;
short l;
char ch;
char chr;//4+4+2+1+1
};
class F
{
public:
int i;
int ii;
int iii;
short j;
char ch;
char chr;//4+4+4+2+1+1
};
class FF
{
public:
short j;
int i;
char ch;
int ii;
char chr;
int iii;//2+2(补全)+4+1+3(补全)+4+1+3(补全)+4=24
};
int main()
{
cout<<"sizeof(double) == "<<sizeof(double)<<endl;//4字节
cout<<"sizeof(float) == "<<sizeof(float)<<endl;//4字节
cout<<"sizeof(int) == "<<sizeof(int)<<endl;//4字节
cout<<"sizeof(short) == "<<sizeof(short)<<endl;//
cout<<"sizeof(char) == "<<sizeof(char)<<endl<<endl;// cout<<"sizeof(A) == "<<sizeof(A)<<endl;
cout<<"sizeof(AA) == "<<sizeof(AA)<<endl;//最宽的类型是8字节的。
cout<<"sizeof(B) == "<<sizeof(B)<<endl;
cout<<"sizeof(C) == "<<sizeof(C)<<endl;
cout<<"sizeof(D) == "<<sizeof(D)<<endl;
cout<<"sizeof(E) == "<<sizeof(E)<<endl;
cout<<"sizeof(F) == "<<sizeof(F)<<endl;
cout<<"sizeof(FF) == "<<sizeof(FF)<<endl;//同样的类型个数,只是顺序变了,就不一样了。
return ;
}
- 字节对齐的准则
- 结构体的首地址能够被其最宽基本类型成员的大小所整除。
- 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍(编译器会在成员之间加上填充字节)如FF
- 结构体的总大小为结构体中最宽基本类型成员大小的整数倍(编译器会在最后成员的后面填充字节)如AA
sixeof计算含有虚函数的类对象的空间大小
#include <iostream>
using namespace std;
class Base
{
public:
Base(int x):a(x){}
void print()
{
cout<<"base"<<endl;
}
private:
int a;
};
class Dervied:public Base
{
public:
Dervied(int x):Base(x-),b(x){}
void print()
{
cout<<"Dervied"<<endl;
}
private:
int b;
};
class A
{
public:
A(int x):a(x){}
virtual void print()
{
cout<<"A"<<endl;
}
private:
int a;
};
class B:public A
{
public:
B(int x):A(x-),b(x){}
virtual void print()
{
cout<<"B"<<endl;
}
private:
int b;
}; int main()
{
Base obj1();
cout<<"size of base obj1 is "<<sizeof(obj1)<<endl;
Dervied obj2();
cout<<"size of Dervied obj2 is "<<sizeof(obj2)<<endl; A a();
cout<<"size of A obj is "<<sizeof(a)<<endl;
B b();
cout<<"size of B obj is "<<sizeof(b)<<endl;
return ;
}
- Base类:占用内存大小是sizeof(int),print()不占用内存空间。4
- Dervied类:比Base类多了一个整形成员,因而多4个字节。8
- A类:因为含有虚函数,因此占用内存除了一个整型变量之外,还包括一个隐含的虚表指针成员,一共8字节
- B类:比A类多了一个整型成员。所以12字节。
普通函数不占用内存,只要有虚函数,就会占用一个指针大小的内存,原因,系统多用了一个指针维护这个类的虚函数表, 并注意到,这个虚函数无论含有多少项(类中含有多少个虚函数)都不会再影响类的大小了。
sizeof计算虚拟继承的类对象的空间大小
#include <iostream>
using namespace std;
class A{};
class B{};
class C:public A,public B{};
class D:virtual public A{};
class E:virtual public A,virtual public B{};
class F
{
public:
int a;
static int b;
};
int F::b = ;
int main()
{
cout<<"sizeof(A) =="<<sizeof(A)<<endl;
cout<<"sizeof(B) =="<<sizeof(B)<<endl;
cout<<"sizeof(C) =="<<sizeof(C)<<endl;
cout<<"sizeof(D) =="<<sizeof(D)<<endl;
cout<<"sizeof(E) =="<<sizeof(E)<<endl;
cout<<"sizeof(F) =="<<sizeof(F)<<endl;
return ;
}
- A类为空,编译器会安排一个char类型给他,用来标记每一个对象。1字节
- C类,多重继承,依然1字节
- D类,虚拟继承A,编译器会安排一个指向父类的指针,为4.因为有了指针,所以不会安排char类型了。
- E类,虚拟继承多个,但是只要一个指针就可以了。
- F类,静态成员的空间不在类的实例中,而是像全局变量一样,在静态存储区,被每一个类的实例共享。
Sizeof的计算看内存分配的更多相关文章
- c++ 汇编代码看内存分配
汇编代码看内存分配 (1). 程序运行时分为存储区域分为 存储区域 存储内容 extra 代码区 存放代码指令,包括除字符串常量的字面值 静态存储区 存放静态变量和全局变量 执行main之前就分配好了 ...
- GlusterFS源代码解析 —— GlusterFS 内存分配方式
原文地址:http://blog.csdn.net/wangyuling1234567890/article/details/24564891 GlusterFS 的内存分配主要有两种方式,一种是内存 ...
- 从一个微型例子看“C/C++的内存分配机制”和“数组变量名与指针变量名”(转)
C++的内存有五大分区:堆区.栈区.自由存储区.全局/静态存储区.常量存储区. 五个数据段:数据段.代码段.BSS段.堆.栈 内存分配方式有三种: 从静态存储区域分配.内存在程序编译的时候就已经分配好 ...
- C++内存分配及变长数组的动态分配
//------------------------------------------------------------------------------------------------ 第 ...
- <转载>内存管理内幕-动态分配的选择、折衷和实现 对malloc内存分配有个简单的描述,对内存管理有个大致的说明
这篇文章看后感觉不错,和我在glibc下的hurdmalloc.c文件里关于malloc的实现基本意思相同,同时,这篇文章还介绍了一些内存管理方面的知识,值得推荐. 原文链接地址为:http://ww ...
- c++内存分配
[导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不 ...
- 【嵌入式开发】C语言 内存分配 地址 指针 数组 参数 实例解析
. Android源码看的鸭梨大啊, 补一下C语言基础 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/detai ...
- php 内存分配
php内核中的内存分配 使用的函数有 emalloc(), erealloc() ,这两个函数分别是malloc(),realloc()函数的封装 关于内存分配有四个容器:cache,小块内存链表,大 ...
- Java静态内存与动态内存分配的解析
1. 静态内存 静态内存是指在程序开始运行时由编译器分配的内存,它的分配是在程序开始编译时完成的,不占用CPU资源. 程序中的各种变量,在编译时系统已经为其分配了所需的内存空间,当该变量在作用域内使用 ...
随机推荐
- adb unknown host service 这个问题的解决,转载
一直没搞明白这个问题咋出现的,但今天看到一个方法,搞定了!原来是豌豆荚占用了 5037 端口导致. 参见原文章:一个豌豆荚引发的血案——关于ADB server didn't ACK的问题 简单来讲, ...
- codesmith生成java类
今天生成的时候的时候找不到类型转换的文件JavaAlias 后台发现我装完codesmith后,没有把类型转换类放入对应的文件 把System-JavaTableNameComments.csmap和 ...
- Android照片墙加强版,使用ViewPager实现画廊效果
转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/12646775 记得关于照片墙的文章我已经写过好几篇了,有最基本的照片墙,有瀑布流模 ...
- Android WebView 重定向问题
webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(Web ...
- 国内首个微信小程序开发者社区www.mntuku.cn
微信小程序开发者社区-微信小程序开发教程-微信小程序最新资讯 - www.mntuku.cn .本站作为专业的微信小程序开发者社区为大家提供:微信小程序开发者交流平台,微信小程序开发教程,微信小程序定 ...
- Spring控制反转(IOC)和依赖注入(DI),再记不住就去出家!
每次看完spring的东西感觉都理解了,但是过了一段时间就忘,可能是不常用吧,也是没理解好,这次记下来. 拿ssh框架中的action,service,dao这三层举例: 控制反转:完成一个更新用户信 ...
- JavaScript 中 申明变量的方式--let 语句
let 语句 - 声明一个块范围变量. 语法 let 变量名 = 初始化值; 例子 "use strict"; let name = '赵敏'; (function opt(){ ...
- 算法入门笔记------------Day4
1.WERTYU 输入一个错位后敲出的字符串,输出打字员本来想打出的字 #include<stdio.h> char *s="`1234567890-=QWERTYUIOP[]\ ...
- [转]如何拷贝一个 SQL Server 的表
这篇短文将介绍几种拷贝 SQL Server 表的方法.第一种方式是最简单的在同一个数据库里将表拷贝到另外一个表.你需要记住的是,拷贝表的时候并不会拷贝表的约束和索引.下面是代码模板和简单的使用方法: ...
- 再谈CSHELL对C程序员的价值
几个礼拜前,介绍了CSHELL.http://www.cnblogs.com/hhao020/p/4974542.html今天再试着介绍下,希望能有更多C程序员留意到它,从中获益. 很多年前,我在调试 ...