One, what is the memory alignment? What do you use for memory alignment?
The so-called memory alignment is a means of optimizing memory access in a compile phase to allow more efficient memory access.
For example, for int x; (This assumes sizeof (int) ==4), because the CPU reads to memory is aligned, if the address of X is not a multiple of 4, then reading this x, you need to read a total of 8 bytes two times, and then stitching it into an int, which is much more troublesome than accessing the aligned X.
Second, how to calculate the size of the memory alignment (theory)?
For simple types, such as int,char,float, their alignment size is its own size, that is, align (int) = = sizeof (int), align (char) ==sizeof (char), and so on.
For a composite type, such as Struct,class, it does not align itself, because the CPU does not directly access a struct instruction. For struct, its alignment means that all of its member variables are aligned, and class is the same.
Let's talk about struct alignment.
The first thing to understand is three points:
1, the alignment of memory is the first address alignment, not the size of each variable is aligned;
2, the structure of the existence of alignment requirements in the structure of each member variable is a memory-aligned;
3, the structure of the alignment in addition to the 2nd also requires that the structure of the array must also be aligned, which means that each adjacent structure is aligned inside.
OK, first know the above 3 points, start contact how to calculate the alignment size.
Programmers can specify the alignment size of some data themselves, specifying the alignment size x by using the following preprocessing directives. (Note here: You can specify only the N-second side of 2 as the alignment size, which may be disregarded for a compiler that specifies the alignment size of 6,9,10)
#pragma pack (x)
//...
#pragma pack ()
So now, maybe everyone has a question, that for int (here suppose sizeof (int) ==4), manually specify the alignment size to be 8, is align (int) equal to sizeof (int) or equal to 8?
Here you can remember that align (x) = min (sizeof (x), packalign), that is, sizeof (x) and the specified alignment size, which is the smaller, the alignment size.
Therefore, the answer to the question above is align (int) =sizeof (int) = 4.
Three, how to calculate the memory alignment size (demo)?
#include <cassert> int main (int argc, char* argv[]) {//Here Specify a alignment size of 1//For a, the actual alignment size is min (s izeof (int), 1) =min (4,1) =1//for B, the actual alignment size is min (sizeof (char), 1) =min (1,1) =1//The compiler will ensure that the first address of the test_a is a 1-byte alignment, at which point A is aligned//More Many highlights: http://www.bianceng.cnhttp://www.bianceng.cn/Programming/cplus///for B, since B requires a 1-byte alignment of the first address, this is clearly appropriate for any address, so a, B are all aligned//for the test_a array, the first test_a is aligned (assuming its address is 0), the first address of the second test_a is (0+5=5), and the two variable test_a for the second a,b are aligned to//ok, justified.
So the whole structure is 5 #pragma pack (1) struct test_a {int A;
Char b;
};
#pragma pack () assert (sizeof (test_a) = = 5); The alignment size specified here is 2//For a, the actual alignment size is min (sizeof (int), 2) =min (4,2) =2//for B, the actual alignment size is min (sizeof (char), 2) =min (1,2) =1//compilation will ensure that the first address of the test_a is 2-byte aligned, at this point a alignment//for B, because B requires the first address 1 byte alignment, which is obviously appropriate for any address, so a,b are aligned//for test_b arrays, the first Test_b is aligned (assuming its address is 0), the first address of the second test_b is (0+5=5), and for the second test_b variable A, it is obvious that address 5 is not aligned to 2 bytes. Therefore, you need to fill 1 bytes after the test_b variable B, at which point the contiguous test_b array is aligned to//ok,QI reasonable.
Therefore the size of the entire structure is 5+1=6 #pragma pack (2) struct Test_b {int A;
Char b;
};
#pragma pack () assert (sizeof (test_b) = = 6); The alignment size specified here is 4//For a, the actual alignment size is min (sizeof (int), 2) =min (4,4) =4//for B, the actual alignment size is min (sizeof (char), 2) =min (1,4) =1//compilation will ensure that the first address of the TEST_A is 4-byte aligned, at this point a alignment//for B, because B requires the first address 1 byte alignment, which is obviously appropriate for any address, so a,b are aligned//for test_c arrays, the first Test_c is aligned (assuming its address is 0), then the first address of the second test_c is (0+5=5), and for the second test_c variable A, it is obvious that address 5 is not aligned to 4 bytes. Therefore, you need to populate 3 bytes after the Test_c variable B, at which point the contiguous Test_c array will snap to//ok, align Reasonable.
Therefore the size of the entire structure is 5+3=8 #pragma pack (4) struct Test_c {int A;
Char b;
};
#pragma pack () assert (sizeof (test_c) = = 8); The alignment size specified here is 8//For a, the actual alignment size is min (sizeof (int), 8) =min (4,8) =4//for B, the actual alignment size is min (sizeof (char), 8) =min (1,8) =1//compilation will ensure that the first address of the TEST_A is 4-byte aligned, at this point a alignment//for B, because B requires the first address 1 byte alignment, which is obviously appropriate for any address, so a,b are aligned//for test_d arrays, the first test_d is aligned (assuming its address is 0), the first address of the second test_d is (0+5=5), for the second test_dThe variable A, obviously address 5 is not aligned to 4 bytes//Therefore, you need to fill in the Test_d variable b after 3 bytes, the contiguous test_d array will align//ok, justified.
Therefore the size of the entire structure is 5+3=8 #pragma pack (8) struct Test_d {int A;
Char b;
};
#pragma pack () assert (sizeof (test_d) = = 8); The alignment size specified here is 8//For a, the actual alignment size is min (sizeof (int), 8) =min (4,8) =4//for B, the actual alignment size is min (sizeof (char), 8) =min (1,8) =1//For C, this is an array, the alignment size of the array is consistent with its unit, so align (c) =align (double) =min (sizeof (double), 8) =min (8,8) =8//For D, the actual alignment size is min (sizeof (char), 8) =min (1,8) =1//compiler will ensure that the first address of Test_a is a 4-byte alignment, at this point a alignment//for B, because B requires the first address 1 byte alignment, which is obviously appropriate for any address, so a,b are aligned//for C, because C Requires a 8-byte alignment of the first address, so the front of the a+b=5, but also after C to make up 3 bytes to align/to D, it is obvious that any address is aligned, at this time the structure size is 4+1+3+10*8+1=89//for the test_e array, the first test_e is aligned (false
Set its address to 0), then the first address of the second test_e is (0+89=89), and for the second test_e variable A, it is obvious that address 89 is not aligned to 4 bytes. Therefore, you need to populate the Test_e variable D with 7 bytes, at which point the contiguous test_e array will be aligned (Note: This is not just to ensure that the next Test_e a,b variable is aligned, but also to ensure that C is aligned, so instead of populating 3 bytes, fill 7 bytes)//ok, justified. So the whole structure is sized (4) + (1+3) + (10*8) + (1+7) =96 #pragma pACK (8) struct Test_e {int A;
Char b;
Double c[10];
Char D;
};
#pragma pack () assert (sizeof (test_e) = = 96);
return 0; }
Four, memory alignment related
You can view the memory layout of a C + + class using the MSVC unpublished compilation option. How to: Start the VS command line, enter CL "Source.cpp"/d1reportsingleclasslayout "CBaseClass1" To view the memory layout of a single class, and enter CL "Source.cpp"/ D1reportallclasslayout to view the memory layout of all classes. Note:/d1reportsingleclasslayout "CBASECLASS1" no space!!
You can use this to see how the compiler arranges alignment against the examples I've mentioned above.
This dongdong is an artifact, similar to the macro expansion of the option (output and processed after the source file), all the internal layout of the truth all show in front of you, including pit brain cells virtual function, virtual function table, virtual base class table, virtual inheritance, such as a series of pit dad.