[C++] Questions about structure memory alignment

1. Memory alignment rules

  1. The first member is at offset 0 from the structure variable.
  2. 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
  3. The total size of the structure is an integer multiple of the largest logarithm (each member variable has a logarithm).
  4. 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).
  5. 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

insert image description here

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:
insert image description here

  • In the case of no byte alignment, variable a occupies 0x00000001this one byte, and variable b occupies 0x00000002~0x000000005these four bytes. If the cpu wants to read variable b from memory, it must first read variable b from variable b. The start address 0x00000002is read , and then this byte 0x0000004is 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 0x00000001this one byte, while variable b occupies 0x00000005~0x00000008these four bytes, then if the cpu wants to read variable b, it will 0x00000005read it directly at once 0x00000008, 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

insert image description here

Guess you like

Origin blog.csdn.net/WL0616/article/details/129261673