Not long ago, in the C ++ program, we encountered a problem about the byte alignment of the struct.
I. Problem description
A struct is defined in the program as follows:
Typedef struct
{
Char name [33];
Int ID;
Int age;
} Person;
Declares an array of the struct:
Person peo [30];
An exception occurs when the ID field is retrieved from the struct to assign a value to a local variable of the int type.
For example, fields in the struct already have initial values.
Peo [0]. ID = 4;
The following assignment statement
Int tempid = peo [0]. ID;
The value 4 cannot be obtained correctly, and the value of tempid is 67108864.
We checked that the value 67108864 is the value of 4 at the high position.
When assigning a value, it should have taken four bytes in the memory: "04 00 00 00"
However, the value can be set to "00 00 00 04.
In the debugging process, the peo [0]. ID value is correct and the number 4 is obtained. After the program executes the above assignment statement:
Tempid is still 67108864.
That is to say, the value in the debugger is correct, but the value of the compiled program is incorrect.
This problem has not occurred for a long time since the program was started. This problem occurs only recently.
It's hard to explain. It is also clear that the program involves network transmission.
However, if the size of the character array in the struct is changed from 33 to 36, everything is normal!
In principle, it must be a bit alignment problem of the struct. But why is there no problem in the previous compilation and use?
How can this problem be solved?
II. Find the cause of the problem.
With the help of the CSDN community leaders, I carefully understood the compilation conditions in the program and understood the nature of this problem in principle.
It is found that the compilation condition "# pram pack (1)" is used in the network module, while that is not added to other modules.
One of the prawns in CSDN explains this: "alignment is for the compiler. The Compiler determines the memory layout based on this. Once compiled into a binary file, the memory layout has been determined. If the two segments of code use different Alignment Methods for the same structure, the values in the memory will be explained differently, one Party who assigns a value thinks that char [33] occupies 36 bytes and fills in 04 00 00 00 from 37th bytes. However, the reading Party thinks that char [33] has only 33 bytes, take four bytes from 34th bytes as the ID."
This time, I think I pointed out the essence of the problem: "If the two sections of code use different Alignment Methods for the same structure, then we will explain the values in the memory differently ". In our program, the initialization part of the struct is aligned according to the default 8-byte structure in the VC compiler. In the network module, because "# pram pack (1)" is used )", when the result is taken from the struct, the compiler considers that the struct is aligned by 1 byte, which eventually leads to problems.
3. Solution
To solve this problem, all the code in the program must use the same alignment for the same structure.
There are two solutions:
First, remove "# pram pack (1)" in the network module. The struct values are aligned in 8 bytes by default in the VC compiler.
The second is to set the structure to be aligned in 1 byte mode. All modules of the program are compiled in this alignment mode.
Set "project"-> "setting..."-> "c/c ++" in VC to 1 Bytes.