Actually, on certain machines, type ‘int’ is allocated storage which begins at address divisible by 4. Such type ‘int’ is called stringent data type. Because of this restriction structures begin at address required by boundary aligned of the stringent data type. Compiler is forbidden to skip bytes at the beginning of storage allocation to structures. Let’s consider and understand this issue through a simple C program,
/* * balignment.c -- program displays the concept of boundary alignment with * structure storage allocation */ #include <stdio.h> #include <stddef.h> typedef struct ALIGN1 { char a; int b; char c; }New1; typedef struct ALIGN2 { int b; char a; char c; }New2; int main(void) { unsigned add_x, add_y; size_t sb; New1 x = {'a', 10, 'b'}; New2 y = {20, 'c', 'd'}; puts("\n**Concept of Boundary Alignment**\n"); printf("size, in bytes, of New1 structure \'x\' and " "New2 structure \'y\': %d, %d\n", sizeof(x), sizeof(y)); puts(""); printf("Address where \'x\' begins: %u, and \'y\' begins: %u\n", &x, &y); puts(""); printf("Let us access respective positions, from start, of each " "member in \'x\' and \'y\'...\n"); puts("Positions in \'x\': \n"); sb = offsetof(New1, a); printf("member \'x.a\' begins at: %d\n", sb); sb = offsetof(New1, b); printf("member \'x.b\' begins at: %d\n", sb); sb = offsetof(New1, c); printf("member \'x.c\' begins at: %d\n", sb); puts(""); puts("Positions in \'y\': \n"); sb = offsetof(New2, b); printf("member \'y.b\' begins at: %d\n", sb); sb = offsetof(New2, a); printf("member \'y.a\' begins at: %d\n", sb); sb = offsetof(New2, c); printf("member \'y.c\' begins at: %d\n", sb); puts(""); return 0; }
Output of the above program is as follows,
**Concept of Boundary Alignment** size, in bytes, of New1 structure 'x' and New2 structure 'y': 12, 8 Address where 'x' begins: 4097266304, and 'y' begins: 4097266288 Let us access respective positions, from start, of each member in 'x' and 'y'... Positions in 'x': member 'x.a' begins at: 0 member 'x.b' begins at: 4 member 'x.c' begins at: 8 Positions in 'y': member 'y.b' begins at: 0 member 'y.a' begins at: 4 member 'y.c' begins at: 5
Notice that structures ‘x’ and ‘y’ both begin at address divisible by four! Further, notice that structure with member list declaration in which stringent data type is listed first takes less storage than structure in which stringent type is declared after first position. Notice in above program, structures both ‘x’ and ‘y’ have the same member list declaration with members being declared in different order but they are allocated different amount of storage. This is due to boundary alignment required by stringent data type.
Fortunately, there’s a ‘macro’ named offsetof(), defined in
size_t offsetof(structure_name, member_name);
First argument is name of structure and second is member of structure whose position is to be determined.
Remember that to reduce memory wastage due to boundary alignment requirement of stringent data type, declare the stringent data type at the top in member list declaration.
Sanfoundry Global Education & Learning Series – 1000 C Tutorials.
- Watch Advanced C Programming Videos
- Apply for C Internship
- Check C Books
- Practice BCA MCQs
- Check Computer Science Books