C langugae : Structure Padding

Data structure alignment is the way data is arranged and accessed in computer memory. It consists of two separate but related issues: data alignment and data structure padding. When a modern computer reads from or writes to a memory address, it will do this in word sized chunks (e.g. 4 byte chunks on a 32-bit system). Data alignment means putting the data at a memory offset equal to some multiple of the word size, which increases the system's performance due to the way the CPU handles memory. To align the data, it may be necessary to insert some meaningless bytes between the end of the last data structure and the start of the next, which is data structure padding.
For example, when the computer's word size is 4 bytes (a byte means 8 bits on most machines, but could be different on some systems), the data to be read should be at a memory offset which is some multiple of 4. When this is not the case, e.g. the data starts at the 14th byte instead of the 16th byte, then the computer has to read two 4 byte chunks and do some calculation before the requested data has been read, or it may generate an alignment fault. Even though the previous data structure ends at the 13th byte, the next data structure should start at the 16th byte. Two padding bytes are inserted between the two data structures to align the next data structure to the 16th byte.
Features
1. Architecture of a computer processor is such a way that it can read 1 word from memory at a time.
2. 1 word is equal to 4 bytes for 32 bit processor and 8 bytes for 64 bit processor. So, 32 bit processor always reads 4 bytes . at a time and 64 bit processor always reads 8 bytes at a time.
3. This concept is very useful to increase the processor speed.
4. To make use of this advantage, memory is arranged as a group of 4 bytes in 32 bit processor and 8 bytes in 64 bit processor.
5. Below C program is compiled and executed in 32 bit compiler. Please check memory allocated for structure1 and structure2 in below program.
Example program for structure padding in C:
#include < stdio.h >
#include < string.h >
/* Below structure1 and structure 2 are same. The differ only in member's allignment */ struct structure1
{
int id1;
int id2;
char name;
char c;
float percentage;
};
struct structure2
{
int id1;
char name;
int id2;
char c;
float percentage;
};
int main()
{
struct strucutre1 a;
struct strucutre2 b;
printf("Size of structure 1 in bytes : %d\n", sizeof(a));
printf("\n Address of id1 = %u", &a.id1);
printf("\n Address of id2 = %u", &a.id2);
printf("\n Address of name = %u", &a.name);
printf("\n Address of c = %u", &a.c);
printf("\n Address of percentage = %u", &a.percentage);
printf("\n\nSize of structure 2 in bytes : %d\n", sizeof(b));
printf("\n Address of id1 = %u", &b.id1);
printf("\n Address of name = %u", &b.name);
printf("\n Address of id2 = %u", &b.id2);
printf("\n Address of c = %u", &b.c);
printf("\n Address of percentage = %u", &b.percentage);
getchar();
return 0;
}

Output:

size of structure1 in bytes : 16
Address of id1 = 1297339856
Address of id2 = 1297339860
Address of name = 1297339864
Address of c = 1297339865
Address of percentage = 1297339868
size of structure2 in bytes : 20
Address of id1 = 1297339824
Address of name = 1297339828
Address of id2 = 1297339832
Address of c = 1297339836
Address of percentage = 1297339840
Structure padding analysis for above C program:

1. In above program, memory for structure1 is allocated sequentially for first 4 members.
2. Whereas, memory for 5th member “percentage” is not allocated immediate next to the end of member “c”.
3. There are only 2 bytes remaining in the package of 4 bytes after memory allocated to member “c”.
4. Range of this 4 byte package is from 1297339864 to 1297339867.
5. Addresses 1297339864 and 1297339865 are used for members “name and c”. Addresses 1297339866 and 1297339867 only is available in this package.
6. But, member “percentage” is datatype of float and requires 4 bytes. It can’t be stored in the same memory package as it requires 4 bytes. Only 2 bytes are free in that package.
7. So, next 4 byte of memory package is chosen to store percentage data which is from 1297339868 to 1297339871.
8. Because of this, memory 1297339866 and 1297339867 are not used by the program and those 2 bytes are left empty.
9. So, size of structure1 is 16 bytes which is 2 bytes extra than what we think. Because, 2 bytes are left empty.

1. Memory for structure2 is also allocated as same as above concept. Please note that structure1 and structure2 are same. But, they differ only in the order of the members declared inside the structure.
2. 4 bytes of memory is allocated for 1st structure member “id1? which occupies whole 4 byte of memory package.
3. Then, 2nd structure member “name” occupies only 1 byte of memory in next 4 byte package and remaining 3 bytes are left empty. Because, 3rd structure member “id2? of datatype integer requires whole 4 byte of memory in the package. But, this is not possible as only 3 bytes available in the package.
4. So, next whole 4 byte package is used for structure member “id2?.
5. Again, 4th structure member “c” occupies only 1 byte of memory in next 4 byte package and remaining 3 bytes are left empty.
6. Because, 5th structure member “percentage” of datatype float requires whole 4 byte of memory in the package.
7. But, this is also not possible as only 3 bytes available in the package. So, next whole 4 byte package is used for structure member “percentage”.
8. So, size of structure2 is 20 bytes which is 6 bytes extra than what we think. Because, 6 bytes are left empty.
Example program to avoid structure padding in C:
#include < stdio.h >
#include < string.h >
/* Below structure1 and structure 2 are same. The differ only in member's allignment */ #pragma pack(1) struct structure1
{
int id1;
int id2;
char name;
char c;
float percentage;
};
struct structure2
{
int id1;
char name;
int id2;
char c;
float percentage;
};
int main()
{
struct strucutre1 a;
struct strucutre2 b;
printf("Size of structure 1 in bytes : %d\n", sizeof(a));
printf("\n Address of id1 = %u", &a.id1);
printf("\n Address of id2 = %u", &a.id2);
printf("\n Address of name = %u", &a.name);
printf("\n Address of c = %u", &a.c);
printf("\n Address of percentage = %u", &a.percentage);
printf("\n\nSize of structure 2 in bytes : %d\n", sizeof(b));
printf("\n Address of id1 = %u", &b.id1);
printf("\n Address of name = %u", &b.name);
printf("\n Address of id2 = %u", &b.id2);
printf("\n Address of c = %u", &b.c);
printf("\n Address of percentage = %u", &b.percentage);
getchar();
return 0;
}
Output:
size of structure1 in bytes : 14
Address of id1 = 3438103088
Address of id2 = 3438103092
Address of name = 3438103096
Address of c = 3438103097
Address of percentage = 3438103098
size of structure2 in bytes : 14
Address of id1 = 3438103072
Address of name = 3438103076
Address of id2 = 3438103077
Address of c = 3438103081
Address of percentage = 3438103082

C langugae : Typedef

The typedef facility is an advanced data feature that enables you to create your own name for a type. It is similar to #define in that respect, but with three differences:
1. Unlike #define, typedef is limited to giving symbolic names to types only and not to values.
2. The typedef interpretation is performed by the compiler, not the preprocessor.
3. Within its limits, typedef is more flexible than #define.
typedef struct complex {
float real;
float imag;
} COMPLEX;
Ordinarily, you would use a header file to hold the definitions of any typedef names that you need to use in multiple source files. However, you must make an exception in the case of typedef declarations for types that contain a variable-length array. Variable-length arrays can only be declared within a block, and the actual length of the array is calculated anew each time the flow of program execution reaches the typedef declaration. An example:
// Structure using typedef: #include < stdio.h >
#include < string.h >
typedef struct student
{
int id;
char name[30];
float percentage;
}status;
int main()
{
status record;
record.id=1;
strcpy(record.name,"Anuj");
record.percentage=72.0;
printf("Records of STUDENT1: \n");
printf("Id is: %d \n", record.id);
printf("Name is : %s record.name);
printf("Percentage is: %f \n\n", record.percentage);
return 0;
}
Records of STUDENT1:
Id is: 1
Name is: Anuj
Percentage is: 72.0000


Free Web Hosting