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资源. 程序中的各种变量,在编译时系统已经为其分配了所需的内存空间,当该变量在作用域内使用 ...
随机推荐
- 不支持C++11 decltype的噩耗
前言:因为公司现在使用vs2008,所以很多c++11的新特性还未能使用,导致写了很多冤枉代码. 最初引擎的数学库非常简单,使用起来也不方便,例如: float FastLerp(const floa ...
- iOS—如何申请苹果公司开发者账号流程详细图文介绍(包括邓白氏编码的申请方法详细介绍)
我们要申请开发者账号,首先就需要先注册一个苹果的apple id,然后再这个账号的基础上去继续,这个相信大家都知道 这是申请appleid的地址:https://appleid.apple.com/a ...
- ZOJ3791_An Easy Game
给出两个等长的字符串,每次需要改变m个数字,每次必须改变k个数字,求从第一个串变化到第二个串的方案数. DP.f[i][j]改变i步后,有j个位置被改变的方案数.然后直接枚举当前改变的几个位置是前面重 ...
- python第二天基础1-1
一.作用域 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. if 1==1: name = 'wupeiqi' print name 二.三元运算 result = 值1 ...
- KMP详解
原文: http://blog.csdn.net/v_july_v/article/details/7041827 从头到尾彻底理解KMP 1. 引言 本KMP原文最初写于2年多前的2011年12月, ...
- 8421BCD码转换为十进制
这个转换和随意的认知是不同的,要了解BCD码和二进制码的区别 #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) ...
- list对象属性排序
Collections.sort(list, new Comparator<ScRel>() { @Override public int compare(Object o1, Objec ...
- 用SYS_CONNECT_BY_PATH进行层级查询时的排序问题
用SYS_CONNECT_BY_PATH进行层级查询时, 对同一级别的节点进行排序,可以加order SIBLINGS by 子句实现 WITH N2 AS( SELECT n.ID, org.&qu ...
- 数学工具之mathgv
做科研时,数学必不可少,有时要看一个方程的很多特性,当然,自己了解的当然好,可要是碰到复杂的,一下子是看不出来,这个时候借助数学工具可以很好地画出来,这里介绍mathgv这个软件. 此软件是开源的,使 ...
- Mac下升级Nodejs
突然发现系统中的nodejs版本比较旧,想升级一下但又不想下载安装包一步一步安装, 发现还是可以很简单用命令行升级的. 首先得清理npm的缓存 sudo npm cache clean -f 安装 n ...