说明
- 对于空类或空结构体生成的对象,内存占用如何?编译器是如何处理的?
空类
#include <iostream>
using namespace std;
class EmptyClass {
};
int main(int argc, char **args) {
EmptyClass n;
cout << sizeof(n) << endl;
return 0;
}
* 运行结果:
1
- 原因:C++标准规定,凡是一个独立的(非附属)对象都必须具有非零大小,生成类对象时需要申请内存,0字节内存申请可能导致对象内存地址是无效的,因此空类生成对象时编译器会主动插入一个char大小的数据。
继承关系中父类是空类
#include <iostream>
class EmptyClass{
};
class Son:public EmptyClass{
int a;
};
int main(int argc, char **args){
EmptyClass a;
std::cout << sizeof a << std::endl;
Son b;
std::cout << sizeof b << std::endl;
return 0;
}
* 运行结果
1
4
- 在编码时,很多处理都是有必要才添加,这里编译器对空类插入一个字节大小的数据,也是有需要才插入的,子类Son并不是空类,因此无需编译器主动插入数据。
空结构体
#include <stdio.h>
struct empty{
};
int main(int argc, char **args){
printf("%d\n", sizeof(struct empty));
return 0;
}
* 运行结果
0
#include <stdio.h>
struct empty{
};
int main(int argc, char **args){
long a;
struct empty b;
long c;
printf("%p, %p, %p, %d\n", &a, &b, &c, sizeof(b));
return 0;
}
* 64位Linux系统上,运行结果
0x7fffae21a7d0, 0x7fffae21a7cf, 0x7fffae21a7d8, 0
- 结果分析:从运行结果可知,空结构体对象的内存占用为1个字节,和空类对象是一样的,虽然编译时大小sizeof求值为0,但是运行时依然会占用一个字节内存,看起来和c++类似,编译器为了空结构对象能够正常,不会导致出现异常,编译时手动插入一个char大小的数据;使用malloc等动态分配内存函数生成的变量也是占一个字节的,malloc等有限制,当传入参数值为0时,依然会分配一个字节大小的内存空间。