Table of contents
1. Memory alignment rules
- The first member is at offset 0 from the structure variable.
- Other member variables should be aligned to an address that is an integer multiple of a certain number (to its number). Alignment number = the smaller of the compiler's default alignment number and the member size.
vs中默认的值是8 Linux中默认的值是4
- The total size of the structure is an integer multiple of the largest logarithm (each member variable has a logarithm).
- If the nested structure is aligned to an integer multiple of its maximum alignment, the overall size of the structure is an integer multiple of the maximum alignment (including the alignment of the nested structure).
- If there is a clear requirement for memory alignment, it can
#pragma pack(n)
be specified (n must be the Nth power of 2), and the smaller of n and the length of the longest data member in the structure is the effective value
Maybe you still don’t understand it just by looking at the above description, so let’s take a look at the specific examples and view explanations:
struct s1{
char c1;
int i;
char c2;
};
//结构体总大小为:12
2. Simple and easy-to-understand memory alignment example
2.1 Simple structure
struct s1
{
char str; //1字节
short x; //2字节
int num; //4字节
};
// sizeof(s1) = 8 // (1+1) + 2 + 4 = 8 第2个加1处的内存是空的
2.2 Structures with bit fields
一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。
struct s2
{
unsigned char a:7; //字段a占用了一个字节的7个bit
unsigned char b:2; //字段b占用了2个bit
unsigned char c:7; //字段c占用了7个bit
}s1;
// sizeof(s1) = 3 // 1 + 1 + 1 = 3
struct s3
{
char t : 4; //4表示在一个字节中占4个比特位
char k : 4;
};
// sizeof(s3) = 1 //0.5 + 0.5 = 1
struct s4
{
char t : 4; //4表示在一个字节中占4个比特位
char k : 4;
unsigned short i : 8;
char a;
};
// sizeof(s4) = 6 //(0.5 + 0.5 + 1) + 2 + (1+1) = 6
// 解释:0.5和0.5占一个字节,两个占4比特的刚好可以放在一个字节中,short为2字节,对齐数是2,所以0.5 + 0.5 + 1中加的1是空的
2.3 Size of Empty Classes
class A {
};
// sizeof(A) = 1
空类,没有任何成员变量和成员函数,编译器是支持空类实例化对象的,对象必须要被分配内存空间才有意义,大小: 1Byte (字节)
2.4 Nested structures
class A {
private:
double dd;
int ii;
int* pp;
};
class Test {
private:
int i;
A a;
double d;
char* p;
};
int main()
{
A a1;
Test test;
cout << sizeof(a1) << endl;
cout << sizeof(test) << endl;
}
// x86(32位操作系统)平台运行结果:40
// x64(64位操作系统)平台运行结果:48
对其数 = 编译器默认的一个对齐数与该成员大小的较小者,vs中默认的值是8
-
x86: The pointer is 4 bytes, the size of class A is 16, and the smaller of 8 and 16 is 8. The memory size is: 8 + 16 + 8 + 4 = 36, and because 36 is not a multiple of the maximum alignment number 8, the memory is offset backwards with a size of 40
-
x64: The pointer is 8 bytes, the class A size is 24, and the smaller of 8 and 24 is 8. The memory size is: 8 + 24 + 8 +8 = 48, 48 is just a multiple of the maximum alignment number 8, so the memory size is 48
3. Why do you need memory alignment?
Byte alignment is mainly to improve memory access efficiency
How much memory the CPU can read at a time depends on the number of bits in the data bus. If it is 16 bits , it can only read 2 bytes at a time . If it is 32 bits , it can read 4 bytes , and the CPU cannot span memory. Interval access .
Suppose there is such a structure as follows:
struct s
{
char a;
int b;
};
Suppose the address space is something like this:
-
In the case of no byte alignment, variable a occupies
0x00000001
this one byte, and variable b occupies0x00000002~0x000000005
these four bytes. If the cpu wants to read variable b from memory, it must first read variable b from variable b. The start address0x00000002
is read , and then this byte0x0000004
is read again , which is equivalent to reading an int, and the CPU reads it twice from the memory.0x00000005
-
However, if byte alignment is performed, variable a still occupies
0x00000001
this one byte, while variable b occupies0x00000005~0x00000008
these four bytes, then if the cpu wants to read variable b, it will0x00000005
read it directly at once0x00000008
, just once All read out. -
Therefore, the root cause of byte alignment is actually the efficiency of CPU reading memory. After alignment, the efficiency of CPU reading memory will be faster. The memory alignment of the structure is the practice of exchanging space for time
4. The number of bytes occupied by the type in different systems
type | win32 | win64 | linux32 | linux64 |
---|---|---|---|---|
char | 1 | 1 | 1 | 1 |
short | 2 | 2 | 2 | 2 |
int | 4 | 4 | 4 | 4 |
long | 4 | 4 | 4 | 8 |
long long | 8 | 8 | 8 | 8 |
float | 4 | 4 | 4 | 4 |
double | 8 | 8 | 8 | 8 |
void*(pointer) | 4 | 8 | 4 | 8 |