本文记录了有关sizeof的一些计算,主要有下面的四种情况:(如有错误,敬请留言)

  1. 使用sizeof()计算普通变量所占用的内存空间
  2. sizeof计算类对象所占用空间的大小-用到了字节对齐
  3. sixeof计算含有虚函数的类对象的空间大小
  4. 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 ;
}
    字节对齐的准则

  1. 结构体的首地址能够被其最宽基本类型成员的大小所整除。
  2. 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍(编译器会在成员之间加上填充字节)如FF
  3. 结构体的总大小为结构体中最宽基本类型成员大小的整数倍(编译器会在最后成员的后面填充字节)如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 ;
}
  1. Base类:占用内存大小是sizeof(int),print()不占用内存空间。4
  2. Dervied类:比Base类多了一个整形成员,因而多4个字节。8
  3. A类:因为含有虚函数,因此占用内存除了一个整型变量之外,还包括一个隐含的虚表指针成员,一共8字节
  4. 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 ;
}
  1. A类为空,编译器会安排一个char类型给他,用来标记每一个对象。1字节
  2. C类,多重继承,依然1字节
  3. D类,虚拟继承A,编译器会安排一个指向父类的指针,为4.因为有了指针,所以不会安排char类型了。
  4. E类,虚拟继承多个,但是只要一个指针就可以了。
  5. F类,静态成员的空间不在类的实例中,而是像全局变量一样,在静态存储区,被每一个类的实例共享。

Sizeof的计算看内存分配的更多相关文章

  1. c++ 汇编代码看内存分配

    汇编代码看内存分配 (1). 程序运行时分为存储区域分为 存储区域 存储内容 extra 代码区 存放代码指令,包括除字符串常量的字面值 静态存储区 存放静态变量和全局变量 执行main之前就分配好了 ...

  2. GlusterFS源代码解析 —— GlusterFS 内存分配方式

    原文地址:http://blog.csdn.net/wangyuling1234567890/article/details/24564891 GlusterFS 的内存分配主要有两种方式,一种是内存 ...

  3. 从一个微型例子看“C/C++的内存分配机制”和“数组变量名与指针变量名”(转)

    C++的内存有五大分区:堆区.栈区.自由存储区.全局/静态存储区.常量存储区. 五个数据段:数据段.代码段.BSS段.堆.栈 内存分配方式有三种: 从静态存储区域分配.内存在程序编译的时候就已经分配好 ...

  4. C++内存分配及变长数组的动态分配

    //------------------------------------------------------------------------------------------------ 第 ...

  5. <转载>内存管理内幕-动态分配的选择、折衷和实现 对malloc内存分配有个简单的描述,对内存管理有个大致的说明

    这篇文章看后感觉不错,和我在glibc下的hurdmalloc.c文件里关于malloc的实现基本意思相同,同时,这篇文章还介绍了一些内存管理方面的知识,值得推荐. 原文链接地址为:http://ww ...

  6. c++内存分配

    [导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不 ...

  7. 【嵌入式开发】C语言 内存分配 地址 指针 数组 参数 实例解析

    . Android源码看的鸭梨大啊, 补一下C语言基础 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/detai ...

  8. php 内存分配

    php内核中的内存分配 使用的函数有 emalloc(), erealloc() ,这两个函数分别是malloc(),realloc()函数的封装 关于内存分配有四个容器:cache,小块内存链表,大 ...

  9. Java静态内存与动态内存分配的解析

    1. 静态内存 静态内存是指在程序开始运行时由编译器分配的内存,它的分配是在程序开始编译时完成的,不占用CPU资源. 程序中的各种变量,在编译时系统已经为其分配了所需的内存空间,当该变量在作用域内使用 ...

随机推荐

  1. MvcPager 免费开源分页控件3.0版发布!

    MvcPager 3.0版在原2.0版的基础上进行了较大的升级,对MvcPager脚本插件重写并进行了大量优化.修复了部分bug并新增了客户端Javascript API等功能,使用更方便,功能更强大 ...

  2. block的解析

    1. 操作系统中的栈和堆 我们先来看看一个由C/C++/OBJC编译的程序占用内存分布的结构: 栈区(stack):由系统自动分配,一般存放函数参数值.局部变量的值等.由编译器自动创建与释放.其操作方 ...

  3. C语言小练习一

    题目要求:国王将金币作为工资,发放给忠诚的骑士.第1天,骑士收到一枚金币:之后两天(第2天和第3天)里,每天收到两枚金币:之后三天(第4.5.6天)里,每天收到三枚金币:之后四天(第7.8.9.10天 ...

  4. php安装libiconv-1.14.tar.gz遇到的问题

    遇到的Error code In file included from progname.c:26:0: ./stdio.h:1010:1: error: ‘gets‘ undeclared here ...

  5. video标签的属性和方法总结

    最近想做一个弹幕插件,查了很多video标签的属性和方法 error属性 在正常读取时候,使用媒体数据的过程中,video元素或audio元素的error属性为null,但是任何时候只要出现错误,er ...

  6. ASP.Net的导出Excel的快速方法,DataTable导出Excel(亲测,非原创)

    //使用方法 ExcelHelper.dataTableToCsv(dt,@"D:\1212.xls");System.Diagnostics.Process.Start(@&qu ...

  7. phpcms V9二次开发之联动菜单筛选 包括box字段的多选 单选 筛选教程

    {php $theurl = "index.php?m=content&c=index&a=lists&catid=$catid";} {php $bran ...

  8. getIdentifier()获取资源Id

    工作需要使用getIdentifier()方法可以方便的获各应用包下的指定资源ID.主要有两种方法:(1)方式一Resources resources = context.getResources() ...

  9. word-wrap&&word-break,奇偶行、列设置样式

    1.word-wrap和word-break区分. 来源场景:机械租赁mvc驾驶员信息查看: 当备注的文字多的时候,第一列的值成这模样: 解决方案:设置table 的td可自动换行.首先table设置 ...

  10. Linux tcpdump 详解

    简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump可以将网络中传送的数据包的 ...