ART中的C++对象内存布局

本文详细探讨了C++11中类的内存布局,包括成员变量对内存占用、空类的存储、对齐规则、虚函数的存储开销、多继承中的虚函数表,以及派生类的内存情况。特别关注了虚函数指针、继承时的内存占用和实例化后的内存示例。
摘要由CSDN通过智能技术生成

C++11中的类所占内存大小主要是由成员变量(静态成员变量除外)决定的,成员函数(虚函数除外)是不计算在内的。

空类的占用存储空间。

class NUllclass {};

NUllclass nullclass;

64和32位下sizeof的返回值都为1。因为C++要求每个实例在内存中都有独一无二的地址。

对齐的影响:

class Base{
 private:
     int a;//四字节
    char p ;//一字节
};

Base base;
sizeof(base);

结果为8字节,需要补齐3字节。

 

  

class Base{
  private:
   int a;//四字节
    char p ;//一字节
public:
Base(int a ,char p):a(a),p(p){
}
};

Base base(100,m)
for(int i=0;i<8;i++){
unsigned char* array=(unsigned char*)(&base);
_android_log_print(4,"cPP11","i:%d,value:%d",i,array[i]);
}

输出依次:

i:0;value:100

i:1;value:0

i:2;value:0

i:3;value:0

i:4;value:109 //m的ascii码

i:5;value:0

i:6;value:0

i:7;value:0

虚函数

class Base{
  private:
   int a;//四字节
    char p ;//一字节
public:
virtual void f(){
_android_log_print(4,"cPP11","f");
};
virtual void g(){
_android_log_print(4,"cPP11","g");
virtual void h(){
_android_log_print(4,"cPP11","h");
Base(int a ,char p):a(a),p(p){
}

};
Base base;

64位sizeof(base)的大小16字节;32位sizeof(base)的大小12字节;

C++类中有虚函数的时候有一个指向虚函数的指针(vptr)32位下指针长度4个字节,64位下8个字节长

类继承自多个基类的时候可能有多个虚函数表指针,可能会占据多个内存空间。此时自然也可以通过虚函数表指针完成对类中虚函数的调用

//第一种只能当虚函数为Public的时候才行,当虚函数为private的时候不行
base.f();
base.g();
base.h();
//第二种 public或者private的时候都可以
//通过对象地址取出虚函数表地址,通过指针偏移取出几个虚函数地址
#if defined (__arm__) 
unsigned int vtableptr = *(unsigned int *)(&base);
unsigned int addrf = *(unsigned int *)vtableptr;
unsigned int addrg = *(unsigned int *)(vatableptr+4);
unsigned int addrh = *(unsigned int *)(vatableptr+8);
typedef void (*Func)(void *);
Func ffunc =(Func) addrf;
Func fgunc =(Func) addrg;
Func fgunc =(Func) addrh;
ffunc(&base);
fgunc(&base);
fhunc(&base);
#else
unsigned int vtableptr = *(unsigned long*)(&base);
unsigned int addrf = *(unsigned long*)vtableptr;
unsigned int addrg = *(unsigned long*)(vatableptr+8);
unsigned int addrh = *(unsigned long*)(vatableptr+16);
typedef void (*Func)(void *);
Func ffunc =(Func) addrf;
Func fgunc =(Func) addrg;
Func fgunc =(Func) addrh;
ffunc(&base);
fgunc(&base);
#endif

在派生类中不对基类的虚函数进行覆盖,同时派生类中还拥有自己的虚函数

class Derived:public Base{
public:
virtual void f1(){
cout<<"Derved::f1"<<endl;
}
virtual void g1(){
cout<<"Derved::g1"<<endl;
}
virtual void h1(){
cout<<"Derved::h1"<<endl;
}
};

在派生类中拥有同名函数的时候会产生覆盖

多继承,无虚函数覆盖的时候:

多继承,有虚函数覆盖的时候:

空的类是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。

(一)类内部的成员变量:

普通的变量:是要占用内存的,但是要注意对齐原则(这点和struct类型很相似)。static修饰的静态变量:不占用内容,原因是编译器将其放在全局变量区。

(二)类内部的成员函数:

普通函数:不占用内存。虚函数:要占用4个以上字节,用来指定虚函数的虚函数表的入口地址。所以一个类的虚函数所占用的大小是不变的,和虚函数的个数是没有关系的。

ART中size_t实际就是unsigned int

一般编译之后的So拖到IDA里面发现函数会多一个参数,第一个参数就编译之后的this指针

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值