Nishith Goswami
Nishith Goswami

Reputation: 363

Structure Padding

I know compiler does Structure padding because CPU can read one word at time ( Word size depends on architecture 16/32/64 ) but I am not able to understand padding behavior for below example.

struct pad 
{ 
  char ch;
};

Size of "struct pad" comes as 1 Byte ( But According to padding concept I suspected 4 byte ( 32 bit architecture ).

Upvotes: 0

Views: 1462

Answers (6)

Govind
Govind

Reputation: 1

Structure padding is a tricky concept. So no need to worry if you dont understand it easily. Consider any structure - If first element is lesser size than the next element in the structure then only padding is necessary and in that case structure padding shall be done for the first element. Wait !!! its not over yet. If you want to find the size of the whole structure there is one more logic/concept to be applied. i.e final size of the structure should be divisible by the biggest size element in the structure.

Now we shall derive it with example.

struct test {  
   char a;
   char b;
   double d;
   int m;
   double dd;
   char c;
   float f;
   double ddd;
   char e;
};

now let is find out the size of each element.

char a; 1

char b; 1

double d; 8

int m; 4

double dd; 8

char c; 1

float f; 4

double ddd; 8

char e; 8

Now we shall apply the structure padding.

char a; 1 ( No padding necessary for the reason explained above)

char b; 1 + 7 (since char is smaller size compared to double, padding of 'double size' is done)*

double d; 8 ( No padding necessary for the reason explained above)

int m; 4 + 4 (since int is smaller size compared to double, padding of 'double size' is done)

double dd; 8 ( No padding necessary for the reason explained above)

char c; 1 + 3*(since char is smaller size compared to float, padding of 'float size' is done)*

float f; 4 + 4 (since float is smaller size compared to double, padding of 'double size' is done)

double ddd; 8 ( No padding necessary for the reason explained above)

char e; 1 ( No padding necessary for the reason explained above)

Now if you add all it comes out to be 54 here when you need to apply second concept that is divisible by biggest element of the structure. Here it is 8, so 54 + 2 = 56 which is divisible by 8.

final size of the above structure is 56.

Upvotes: 0

CiaPan
CiaPan

Reputation: 9570

First, it's rather a compiler, not a CPU who adds padding—however the compiler adds padding respective to the specific target CPU capabilities (mostly to its data bus width).

Padding bytes are added for efficient memory access. When CPU reads or writes a 2-byte word on an even address through a 16-bit bus the transfer can be done in one cycle. However if 2-byte data is located at an odd address, it occupies a 'lower' half of one even-addressed word and an 'upper' half of another even-addressed word in memory. CPU then must perform two bus cycles: one for each memory word occupied by your data, each time utilizing only half the bus width for actual transfer.

For a 32-bit bus a 2-byte or 4-byte piece of data can also require two cycles if it spans across the double word (4-byte) boundary. Similar effects happen on 64-bit bus. That's why the padding: a compiler adds bytes to align data to the boundaries where they can be efficiently accessed.

Padding may happen if a shorter member is followed by a longer one.

A structure containing 1-byte members only

struct BBB {
    byte  b1;
    byte  b2;
    byte  b3;
}

doesn't need any padding - each byte can be read or written in one cycle.
Similary

struct III {
    int   i1;
    int   i2;
    int   i3;
}

provided the structure is aligned to the even boundary (according to its first member requirement) all members are properly aligned, too.

struct BI {
    byte  b;
    // one byte added here
    int   i;
}

Here one byte is added so that the 2-byte int is aligned to 2-bytes boundary.

struct IB {
    int   i;
    byte  b;
    // one byte added here
}

Surprise! Why the additional byte at the end? What data needs aligning here...?
Well, suppose you declare an array:

struct IB arr[4];

Then the array data is arranged in memory like this:

int     arr[0].i
byte    arr[0].b
// byte arr[0] padding
int     arr[1].i
byte    arr[1].b
// byte arr[1] padding
int     arr[2].i
byte    arr[2].b
// byte arr[2] padding
int     arr[3].i
byte    arr[3].b
// byte arr[3] padding

Every byte member at the end of the structure got 'extendend' to two bytes, so that the int in the next array item is aligned to an even address. Without padding every second array item would have its int member misaligned.

For a 32-bit bus up to 3 bytes of padding may be used:

struct BL {
    byte  b;
    // 3 bytes added
    long  l;
}

so that 4-bytes long is placed at 4-bytes boundary.

Upvotes: 2

MooseBoys
MooseBoys

Reputation: 6793

You're confusing the concepts of memory padding with memory controller addressing (which usually does operate on words).

For various reasons C imposes standard struct alignment requirements (though these can often be overridden using compiler #pragmas). According to the standard, the struct you defined should indeed have a size of 1 byte.

When executing this code on an x86 CPU, however, the memory controller will load the 4-byte aligned word and the CPU will extract the 1-byte value for the struct. This occurs regardless of whether the struct is 4-byte aligned or not, and has no impact on performance.

Upvotes: 1

Nerdy
Nerdy

Reputation: 1099

Size of the defined structure is 1 byte no padding is used here. Because char occupies 1 byte of memory and there are no other data type.

struct s1
{
  char a;
  char b;
}

This returns size of structure as 2. Structure padding is done for easier and faster processing of address when different size variables are used.

Upvotes: 0

Kun Ling
Kun Ling

Reputation: 2219

Here, the struct actually has 1B size, no padded is needed here.

The actual structure padding is like the following:

#include <stdio.h>
struct char_int {
        char a;
        // 3B padding here.
        int b;
};

int main() {
        struct char_int struct_a;
        struct_a.a = 0;
        struct_a.b = 12;
        printf("sizeof(struct_a):%d, &struct_a.a:0x%x, &struct_a.b:0x%x\n",
                        sizeof(struct char_int), &struct_a.a, &struct_a.b);
        return 0;
}

On my environment, GCC 4.9.2 RHEL AMD64 5.9. the output is as following:

  sizeof(struct_a):8, &struct_a.a:0x36a41fd0, &struct_a.b:0x36a41fd4

When allocate memory for the above structure in the stack or in the heap, there will be 3 byte padded between char a and int b since here field char_int.b has address with offset 4, while file char_int.a only has 1 Byte.

Upvotes: 0

Michael Burr
Michael Burr

Reputation: 340446

A char type can be accessed efficiently on any address boundary, so no padding is necessary.

Upvotes: 2

Related Questions