C Language byte alignment problem

Source: Internet
Author: User

First, what is byte alignment?
The memory space in modern computers is divided by byte (byte), in theory, it seems that access to any type of variable can start from any address, but the reality is that when accessing a particular variable, it is often accessed at a specific memory address, rather than sequentially one-by-one emissions. In order for the CPU to be able to quickly access variables, the starting address of the variable should have some characteristics, known as "byte alignment." For example, a 4-byte int, whose starting address should be on a 4-byte boundary, where the starting address can be divisible by 4.
In C, a struct is a composite data type whose constituent elements can be variables of basic data types (such as int, long, float, and so on) or data units of composite data types (such as arrays, structs, unions, etc.). In structs, the compiler allocates space for each member of the struct according to its natural boundary (alignment), and the individual members are stored sequentially in memory in the order in which they are declared, and the address of the first member is the same as the address of the entire structure.

Second, the role and reason of byte alignment
The processing of storage space varies greatly with each hardware platform. Some platforms (for example, the SPARC system is very strict with byte alignment) for some specific types of data can only be accessed from certain addresses. Other platforms may not, but if data storage is not aligned according to the requirements of its platform, it can result in loss of access efficiency. For example, some platforms (for example, x86) each read from the even address, if an int (assuming 32-bit) if it is stored at the beginning of the even address, then a read cycle can be read out, and if it is stored at the beginning of the odd address, it takes 2 read cycles, The int data can be obtained by piecing together the high and low bytes of the two read-out results. The latter is obviously a lot less efficient in reading, but the storage space may be more compact than the former, which is also the space and time trade-offs.

Three, byte alignment principle
What are the principles that the compiler aligns? Before we continue to analyze specific byte alignment issues, let's look at a few important basic concepts:
1. The alignment value of the data type itself: on a 32-bit x86 machine, its own alignment value is 1 bytes for char type data, its own alignment is 2 bytes for the short type, and for Int,long, the float type, its own alignment value is 4 bytes;
For a long long,double type of 8 bytes, the pointer type for the base type (which is essentially unsigned long) is aligned to 4 bytes.
2. The self-aligning value of a struct or class: The value that is the largest of its members in its own alignment value.
3. Specify the alignment value: The specified alignment value when #pragma pack (value) is values.
4. Compiler default alignment value: Generally the same as the CPU word length, on 32-bit machine is 4 bytes, 64-bit machine is 8 bytes. When alignment values are not specified, the compiler uses the default alignment values.
5. Valid alignment values for data members, structs, and classes: The value that is small for its own alignment value and for the specified alignment value.

With these values, we can easily discuss the members of a specific data structure and its own alignment. The valid alignment value n is the value that is ultimately used to determine how the data is stored, most importantly. A valid alignment of n is the "alignment on n", which means that the data "holds the starting address%n=0". Data variables in the structure are emitted in a defined order of precedence. The starting address of the first data variable is the starting address of the structure. The member variables of a struct are aligned with the emission, and the structure itself is rounded according to its own valid alignment value (that is, the total length of the struct member variable is required to be an integer multiple of the effective alignment value of the struct.)


Four, byte alignment example analysis
According to the principle of byte alignment, with the following example to understand, it is clear.
Example Analysis:
analysis example B;
struct B {
Char b;
int A;
Short C;
};
Suppose B starts discharging from the address space 0x0000. In this example, the specified alignment value is not defined, and in the author's environment, the value defaults to 4. The first member variable B has a self-aligning value of 1, which is smaller than the specified or default alignment value of 4, so its valid alignment value is 1, so its storage address 0x0000 conforms to 0x0000%1=0. The second member variable A has its own alignment value of 4, so the valid alignment value is also 4, so it can only be stored in the starting address of 0x0004 to 0x0007 four contiguous byte space, review 0x0004%4=0, and immediately close to the first variable. The third variable, C, has its own alignment value of 2, so the valid alignment value is also 2, which can be stored in the two byte space of 0x0008 to 0x0009, conforming to 0x0008%2=0. So everything from 0x0000 to 0x0009 is stored in B content. Then look at the data structure B's own alignment value for its variable maximum alignment value (here is B) so is 4, so the structure of the effective alignment value is also 4. 0x0009 to 0x0000=10 bytes, (10+2)%4=0 according to the requirements of the structural rounding. So 0x0000a to 0x000b is also occupied by struct B. So B has a total of 12 bytes from 0x0000 to 0x000b, sizeof (struct B) = 12;

Similarly, analyze the above example C:
#pragma pack (2)/* Specify 2-byte alignment */
struct C {
Char b;
int A;
Short C;
};
#pragma pack ()/* To cancel the specified alignment, restore the default alignment */
The first variable B has its own alignment value of 1, the specified alignment value is 2, so its valid alignment value is 1, assuming that C starts with 0x0000, then B is stored in 0x0000, conforms to 0x0000%1= 0, the second variable has its own alignment value of 4, and the alignment value is 2, so the valid alignment value is 2. So the order is stored in 0x0002, 0x0003, 0x0004, 0x0005 four consecutive bytes, in accordance with 0x0002%2=0. The third variable, C, has its own alignment value of 2, so the valid alignment value is 2, which is stored sequentially
In 0x0006, 0x0007, in accordance with 0x0006%2=0. So from 0x0000 to 0x00007 a total of eight bytes is stored in the C variable. and C has its own alignment value of 4, so the valid alignment value for C is 2. And 8%2=0,c only takes up eight bytes of 0x0000 to 0x0007. So sizeof (struct C) =8.


V. Summary
With the above explanation, I believe you should have a clear understanding of the concept of byte alignment in C language. In the network program, it is important to master this concept, oh, between the different platforms (such as between Windows and Linux) to pass 2 of streams (such as the structure), then in these two platforms must define the same alignment, but also pay attention to the big end of the byte and the small side of the problem, Otherwise it will somehow appear some strange mistakes, but it is difficult to troubleshoot the OH ^_^.

Vi.. Attached source code

[CPP]View Plaincopyprint?
  1. /******************************************************************************
  2. Copyright by Javacode007, all rights reserved!
  3. filename:structsize.c
  4. author:javacode007
  5. date:2012-8-5
  6. version:1.0
  7. Description: Structure type size test
  8. ******************************************************************************/
  9. #include <stdio.h>
  10. struct A
  11. {
  12. Char c;
  13. Short S;
  14. int i;
  15. };
  16. #pragma pack (1)/* Specify 1-byte alignment */
  17. struct Pa
  18. {
  19. Char c;
  20. Short S;
  21. int i;
  22. };
  23. #pragma pack ()/* To cancel the specified alignment, restore the default alignment */
  24. struct B
  25. {
  26. Char c;
  27. int i;
  28. Short S;
  29. };
  30. #pragma pack (2)/* Specify 2-byte alignment */
  31. struct PB
  32. {
  33. Char c;
  34. int i;
  35. Short S;
  36. };
  37. #pragma pack ()/* To cancel the specified alignment, restore the default alignment */
  38. int Main ()
  39. {
  40. struct A StA;
  41. struct PA STPA;
  42. struct B StB;
  43. struct PB STPB;
  44. printf ("sizeof (A) =%d, &c =%p, &s =%p, &i =%p\r\n", sizeof(StA), &STA.C, &STA.S , &STA.I);
  45. printf ("sizeof (PA) =%d, &c =%p, &s =%p, &i =%p\r\n", sizeof(STPA), &STPA.C, &STP A.S, &STPA.I);
  46. printf ("sizeof (B) =%d, &c =%p, &s =%p, &i =%p\r\n", sizeof(StB), &STB.C, &STB.S , &STB.I);
  47. printf ("sizeof (PB) =%d, &c =%p, &s =%p, &i =%p\r\n", sizeof(STPB), &STPB.C, &STP B.S, &STPB.I);
  48. return 0;
  49. }
/******************************************************************************copyright by Javacode007, all Rights reserved! FILENAME:STRUCTSIZE.CAUTHOR:JAVACODE007DATE:2012-8-5VERSION:1.0DESCRIPTION: Structure type size test *********    /#include <stdio.h>struct a{char c;    Short S; int i;};    #pragma pack (1)/* Specifies 1-byte alignment */struct pa{char c;    Short S; int i;};    #pragma pack ()/* Cancels the specified alignment, restores the default alignment */struct b{char c;    int i;    Short S;    }; #pragma pack (2)/* Specifies 2-byte alignment */struct pb{char c;    int i;    Short S;    }; #pragma pack ()/* Cancels the specified alignment, restores the default alignment */int main () {struct A StA;    struct PA stpa;    struct B StB;    struct PB STPB;    printf ("sizeof (A) =%d, &c =%p, &s =%p, &i =%p\r\n", sizeof (StA), &AMP;STA.C, &AMP;STA.S, &AMP;STA.I); printf ("sizeof (PA) =%d, &c =%p, &s =%p, &i =%p\r\n", sizeof (STPA), &AMP;STPA.C, &AMP;STPA.S, &AMP;STPA.I)    ; printf ("sizeof (B) =%d, &c =%p, &s =%p, &i =%p\r\n ", sizeof (StB), &AMP;STB.C, &AMP;STB.S, &AMP;STB.I);         printf ("sizeof (PB) =%d, &c =%p, &s =%p, &i =%p\r\n", sizeof (STPB), &AMP;STPB.C, &AMP;STPB.S, &AMP;STPB.I);    return 0; }



Output Result:

C Language byte alignment problem

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.