How does C/C++ "padding work?

Asked

Viewed 941 times

19

In several responses here at Stackoverflow I have noticed users commenting on padding in data structures.

struct {
  int a;
  char b;
  float d;
}
  1. What is this one padding (filling) that exists between the fields of a struct?
  2. It occurs only in structs or may occur in classes also?
  3. How can I avoid it? (Optimize code)

1 answer

15


What is

This is used to facilitate the work of reading memory and placing in registers. Registrants work with a fixed size according to their architecture. Ideally, the data will fit within this size. Then the data is stored in words. The padding (or fill) aligns this data by adding bytes not significant. Compilers do this by default. If you need a specific behavior is necessary the use of directives indicating the necessary form.

For all purposes classes are structures (structs) and operate in the same way.

Wastage

In your example the structure will probably have 12 bytes (32-bit architecture) since the member b will be filled with 3 bytes extras to make the padding. So all members will have 4 bytes. This number is obtained taking into account that most architectures have a word with 4 bytes size.

Evidently on 64-bit architectures the damage is even greater (and it is possible to have even bigger fill), you can have up to 7 bytes waste. The word often reflects how registrants are used in processors. Note that I am using common data on major architectures. C and C++ compilers are liberal about the size of almost all types applying a minimum size.

Eliminate the padding may optimize in some cases memory consumption but may cause other performance problems. Reading memory data in different architecture word sizes need extra processing. In most cases it does not make up for the exchange.

Saving

Of course there are cases that there may be natural filling keeping the use of the word:

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 word alignment. So thinking membership order can be quite useful.

This is the most recommended way to solve the problem. It has no downside to 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 over and over again in another structure. Save some bytes not worth the effort. Save some bytes multiplied by millions of times can make a difference.

But it is also possible to control how the padding is done with directives (often non-standard among compilers). Example:

When you really need it, we can do the Packing. Examples in packaging.

#pragma pack(1)

In Microsoft C++ like others compilers that follow the C standard, makes the size 1 byte effectively eliminating any padding. Of course members over 1 byte will have their normal size. This indicates the minimum size the member should have. In GCC you could optionally use:

__attribute__((packed))

This informs that a specific member should not receive the padding. This is more flexible but can be unsafe on certain platforms.

Packaging members is risky and if you’re not sure what you’re doing you might get unexpected results. Well, almost everything in C and C++, but some features are more risky.

Even the form considered standard is not considered portable.

Obviously we can use the operator sizeof 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, he considers the completion.

Reinforcement that rarely these procedures are necessary. 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 fundamental.

Wikipedia article.

Interesting article.

  • I will await the conclusion of your reply before voting, but so far you have given a basic idea of what it is

  • and how do you know int and the float has 4 bytes each and the memory alignment should be 4 bytes? __attribute__((packed)) is universal among all compilers?

  • @bigown, when you have time, please complete your answer, I’m quite interested in reading her.

  • @Kaminary, I’m sorry, I have a health problem and I can’t stay out of bed for long. But the page is open and until I take the warning, I won’t give it up and I’ll get better.

  • @Pequiamarelo gave an improved and I will improve more as soon as I can. I do not know if you have 4 bytes I think it has based on what architectures mainstream use. This attribute is not universal, not this way. I will further improve this part yet.

  • @Bigown No problem, it is not a deadly question that needs to be answered in 1 day ^^

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.