What is
This is used to facilitate the work of memory reading and placement in registers. Registered users work with a fixed size according to their architecture. Ideally, the data should fit within this size. Then the data is stored in "words". padding (or padding) aligns this data by adding non-significant bytes . compilers do this by default. If you need a behavior you need the use of directives indicating the required form.
For all effects classes are structures and work in the same way.
Waste
In your example, the structure will probably have 12 bytes since the b
member will be populated with 3 extra bytes to do the padding . So all members will have 4 bytes. This number is obtained taking into account that most of the architectures have a with 4 bytes in size.
Of course in 64-bit architectures the damage is even greater (and you can have even more fill), you can have up to 7 of wastage. The word usually reflects how registrations are used in processors. Note that I am using common data in the main architectures. Compilers C and C ++ are liberal as to the size of almost all types if applying a minimum size.
Eliminating padding can optimize memory consumption in some cases, but may cause other performance problems. Reading data from memory in different sizes of the architecture word requires extra processing. In most cases it does not make up for the trade.
Saving
Of course there are cases where there may be natural filling by keeping the floor:
struct {
int a;
char b;
char c;
char d;
char e;
float f;
}
This structure may well have the same 12 bytes . The 4 chars
fit in the word alignment. So thinking the order of the members can be quite useful.
This is the most recommended way to resolve the problem. It has no disadvantage for the software itself. Of course eventually you will have to put data in an order that is not so intuitive to read.
Even in this case you will only have a clear memory consumption advantage if the structure is used repeatedly in another structure. Saving some bytes is not worth the effort. Saving some bytes multiplied by millions of times can make a difference.
But you can also control how padding is done with policies (often not standardized across compilers). Example:
When you really need it, we can do the packing . Examples in packaging.
#pragma pack(1)
In C ++ from Microsoft, like other compilers that follow the C pattern , makes the size byte effectively eliminating any padding . Of course members with more than 1 byte will have their normal size. This indicates the minimum size the member should have. In GCC you could optionally use:
__attribute__((packed))
In this way it is advised that a specific member should not receive padding . This is more flexible but can be insecure on certain platforms.
Packing members is risky and if you are not sure what you are doing you may have unexpected results. Well, almost everything in C and C ++, but some features are more risky.
Even the standard form is not considered portable.
Obviously we can use the sizeof
operator to find out the actual size of the data. This operator always returns the exact size that the data occupies in memory and not the sum of its members. That is, it considers the padding.
Strengthening that these procedures are rarely needed. Almost always the attempt to package structures is premature optimization. By making the use of structures less intuitive the recommendation is to avoid until proven to be critical.
Wikipedia article .
Interesting article .