C++:Struct结构体和内存使用
struct A
{
int age;
string name;
}
C++中的结构体与类的区别: (1)class中默认的成员访问权限是private的,而struct中则是public的。 (2)class继承默认是private继承,而从struct继承默认是public继承。
内存的空间使用
空的类是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。
(一)类内部的成员变量:
普通的变量:是要占用内存的,但是要注意对齐原则(这点和struct类型很相似)。
static修饰的静态变量:不占用内容,原因是编译器将其放在全局变量区。
(二)类内部的成员函数:
普通函数:不占用内存。
虚函数:要占用4个字节,用来指定虚函数的虚拟函数表的入口地址。所以一个类的虚函数所占用的地址是不变的,和虚函数的个数是没有关系的
结构体所占内存:
结构体存在内存对齐,类(对象)也如此,甚至于所有变量在内存中的存储也有对齐一说(只是这些对程序员是透明的,不需要关心)。实际上,这种对齐是为了在空间与复杂度上达到平衡的一种技术手段,简单的讲,是为了在可接受的空间浪费的前提下,尽可能的提高对相同运算过程的最少(快)处理。
结构体的成员地址对其原则:
一般都是满足成员的字节总数的整数倍地址排布
struct A
{
char a1; //1个字节
int a2; //4个字节,要与4字节对齐,所以分配至第4个字节处
short a3; //2个字节, 上述两个成员过后,本身就是与2对齐的,所以之前无填充
}; //整个结构体,最长的成员为4个字节,需要总长度与4字节对齐,所以, sizeof(A)==12
struct B
{
char b1; //1个字节
__int64 b2; //8个字节,位置要与8字节对齐,所以分配到第8个字节处
int b3; //4个字节,成员d结束于15字节,紧跟的16字节对齐于4字节,所以分配到16-19
short b4; //2个字节,成员e结束于19字节,紧跟的20字节对齐于2字节,所以分配到20-21
A b5; //结构体长为12字节,最长成员为4字节,需按4字节对齐,所以前面跳过2个字节,到24-35字节处
char b6; //1个字节,分配到36字节处
int b7; //4个字节,要对齐4字节,跳过3字节,分配到40-43 字节
}; //整个结构体的最大分配成员为8字节,所以结构体后面加5字节填充,被到48字节。故:
//sizeof(B)==48;
int main()
{
B b = { 'b',122,232,12,{'a',12,23},'c',432 };
//这里要注意一个问题,cout直接输出char类型的地址,输出的地址会出现乱码的情况,
//因为out对于char* 参数,直接输出字符串(程序将其类型当做一个字符串的首地址)--对于其他类型都是输出指针
//字符串以空终止符(‘\0’)结尾, & b是一个char * 变量,但 & b保存的字符没有终止符,所以输出乱码
//可以通过强转成void类型进行输出或者直接使用printf输出
//cout << &b.b1 << endl;
printf("%p\n", &b.b1);
cout << (void*)(&b.b1) << endl;
cout << &b.b2 << endl;
cout << &b.b3 << endl;
cout << &b.b4 << endl;
cout << &b.b5 << endl;
cout << (void*)(&b.b5.a1) << endl;
cout << &b.b5.a2 << endl;
cout << &b.b5.a3 << endl;
cout << (void*)(&b.b6) << endl;
cout << &b.b7 << endl;
cout << &b << endl;
//输出:
//0034F700
//0034F700
//0034F708
//0034F710
//0034F714
//0034F718
//0034F718
//0034F71C
//0034F720
//0034F724
//0034F728
//0034F700
system("pause");
return 0;
}
从以下表格中可以看出