C++中子类与父类的内存分别情况
1. unbunt上C++子类与父类内存的分别情况
1.1 只有一个父类的情况
1.1.1 上代码
#include <stdio.h>
class A {
public:
A() {};
~A() {};
int a;
int b;
};
class B : public A {
public:
B() {};
~B() {};
int c;
int d;
};
int main() {
B *b = new B();
printf("b:%p\n", b);
printf("%p, %p, %p, %p\n", &b->a, &b->b, &b->c, &b->d);
return 0;
}
1.1.2 查看运行结果
$./a.out
b:0x152e010
0x152e010, 0x152e014, 0x152e018, 0x152e01c
1.1.3 结论
从运行结果可以看出, 内存中先存储父类的变量成员,再保存子类的变量成员
1.2 多个父类的情况
1.2.1 上代码
#include <stdio.h>
class A {
public:
A() {};
~A() {};
int a;
int b;
};
class B {
public:
B() {};
~B() {};
int c;
int d;
};
class C : public A, public B {
public:
C() {};
~C() {};
int e;
int f;
};
int main()
{
C *c = new C();
printf("c:%p\n", c);
printf("%p, %p, %p, %p, %p, %p\n", &c->a, &c->b, &c->c, &c->d, &c->e, &c->f);
return 0;
}
1.2.2 运行结果
c:0x1f91010
0x1f91010, 0x1f91014, 0x1f91018, 0x1f9101c, 0x1f91020, 0x1f91024
1.2.3 结论
遇到多个父类的情况下, 内存中先存储第一个父类的成员变量,其次是第二个,一直到第N个,最后才保存子类的成员变量。
android上FrameWork层用的是C++代码,编译是arm-linux-androideabi-g++ 或者是clang编译器,子类与父类的内存分布情况也是 先第一个父类,其次第二个,一直到第N个,最后才保存子类的成员变量。
先前遇到一个踩内存的问题,原因就在于第一个父类中增加了一个成员变量m,并用宏隔开,
1.so使用此子类时,编译时没有使能此宏,
2.so使用此子类时,编译时使能了这个宏,
运行时,2.so与1.so交互时, 处理同一段内存时, 1.so 认为没有成员变量m, 2.so认为有成员变量
这样内存出现偏移, 2.so操作成员变量m时, 实际上更改了1.so中 子类的第二个父类的内存,第二个父类时 RefBase,所以出现了各种莫名奇妙的问题。哎 …… 定位了一星期,才发现这个低级错误。
用图来表示如下:
在2.so中操作 成员m时, 实际上修改的是 1.so中的成员c
于是再在1.so中操作c时,会有各种莫名其妙的错误。