Analyze Sizeof in C language
First, the concept of SizeOf is a single operator in the C language, such as other operators , - etc. It is not a function. The SIZEOF operator gives the storage size of its operand in byte. The number of operands can be an expression or a type name enclosed in parentheses. The storage size of the operand is determined by the type of operand.
Second, the use of SIZEOF 1, used for data types
SIZEOF use form: sizeof (Type)
The data type must be enclosed in parentheses. Such as SIZEOF (int).
2, used for variables
SizeOf use form: sizeof (var_name) or sizeof var_name
The variable name can be horn without parentheses. Such as sizeof (var_name), sizeof var_name, etc. are all correct forms. Usage of brackets is more common, most programmers use this form.
Note: The SIZEOF operator cannot be used for function types, incomplete types or bit fields. Incomplete type refers to a data type with unknown storage size, such as an unknown storage size, an unknown content of the content or a combination type, a Void type, and the like.
If SIZEOF (MAX), if the variable max is defined as int max (), sizeof (char_v) If CHAR_V is defined as char char_v [max] and Max is unknown, SizeOf (Void) is not correct.
Third, the result type of Sizeof operator is Size_T, it is on the header file
Typedef is a unsigned int type. This type ensures that the byte size of the maximum object established can be accommodated.
1. If the operand has a type char, unsigned char or signed char, the result is equal to 1.
ANSI C officially specifies that the character type is 1 byte.
2, int, unsigned int, unsigned long, flos 2, 4, 4, 4, 8, 10.
3. When the operand is a pointer, SIZEOF depends on the compiler. For example, in Microsoft C / C 7.0, the NEAR class norm is 2, FAR, and the HUGE class pointer is 4. General Unix's pointer one is 4.
4. When the operand has an array type, the result is the total number of bytes of arrays.
5. SIZEOF of the joint type operand is the number of bytes of its maximum byte member. SIZEOF of the structure type operand is the total number of bytes of this type of object, including any pad.
Let us see the following structure:
Struct {char b; double x;} a;
SIZEOF (A) = 12 on some machines, and general SizeOf (char) sizeof (double) = 9.
This is because the compiler is inserted into the space in the structure in the structure to control the address alignment of each member object when considering alignment problems. If the Double type of structural member X is to be put on the address of 4.
6. If the operand is the shape parameter or function type in the function, SIZEOF gives the size of its pointer.
Fourth, the relationship between SIZEOF and other operators SIZEOF has a priority of Level 2, ratio /,% and other 3 operators. It can form an expression with other operators. Such as i * sizeof (int); where i is an int type variable.
5. SizeOf's main purpose 1, one of the SizeOf operators is to communicate with routines such as storage allocation and I / O systems. E.g:
Void * malloc (size_t size), size_t fread (Void * Ptr, Size_t size, size_t nmemb, file * stream).
2, another main purpose of SizeOf is to calculate the number of elements in arrays. E.g:
Void * MEMSET (Void * S, INT C, SIZEOF (S)).
6. It is recommended that due to the number of bytes of operands may change when implementation, it is recommended to replace constant calculations in SIZEOF when it involves an operational digital size. ============================================================================================================================================================================================================= =====================================
This paper mainly includes two parts, the first partial focus is introduced in the VC, how to use SizeOf to see the size of the structure, and the problem that is easy to appear, and give a solution method, the second part summarizes the main usage of SizeOf in the VC. .
1, SIZEOF application in structure
Please see the following structure:
Struct MyStruct
{
Double DDA1;
Char DDA;
Int Type
}
What results do you have to use SIZEOF to the structure ?truct? How much is SIZEOF (MySTRUCT)? Maybe you will seek this:
Sizeof (mYStruct) = sizeof (double) sizeof (char) sizeof (int) = 13
But when you test the size of the above structure in the VC, you will find SizeOf (MyStruct) to 16. Do you know why you will find such a result in VC?
In fact, this is a special process of VC on variable storage. In order to improve the storage speed of the CPU, VC is "aligned" processing on the starting address of some variables. By default, the VC specifies the starting address of each member variable to store the start address of the structure must be a multiple of the number of bytes occupied by the type of variable. The alignment (VC6.0, 32-bit system) of the common type is listed below.
Type alignment (the offset of the start address of the variable is relative to the start address of the structure)
The char offset must be a multiple of SizeOf (char) 1
The INT offset must be a multiple of SizeOf (int) 4
Float offset must be a multiple of Sizeof (Float)
Double offset must be a multiple of Sizeof (double)
The Short offset must be a multiple of SizeOf (Short)
Each member variable is sequentially applied in sequence according to the order in the structure, while adjusting the position according to the above alignment, and the byte VC of the vacancy will automatically populate. At the same time, VC is multiple of the number of byte boundary of the structure of the structure (ie, the number of bytes occupying the maximum space occupied by the maximum space), it will automatically be automatically applied to the last member variable. Fill the byte of the vacant.
The following examples use the previous example to explain how the VC is stored.
Struct MyStruct
{
Double DDA1;
Char DDA;
Int Type
}
When allocating space for the above structure, the VC is allocated to the first member DDA1 allocated space according to the order and alignment of the member variable, and the start address of the start address is the same (just the offset 0 is just Sizeof). (double), the member variable takes up SIZEOF (Double) = 8 bytes; next for the second member DDA allocation space, then the next one can allocate the offset of the start address of the structure 8. It is the multiple of sizeof (char), so the DDA is stored in the place where the offset is 8 satisfies the alignment. The member variable takes up SIZEOF (CHAR) = 1 byte; next to the third member TYPE allocation space At this time, the next one can allocate the offset of the start address of the structure is 9, not the multiple of sizeof (int) = 4, in order to satisfy the alignment to the offset constraint, VC automatically fills 3 bytes (These three bytes do not have anything), then the next device can be allocated to 12 of the offset of 12, just a multiple of sizeof (int) = 4, so putting Type in offset Where is 12, the member variable takes up SIZEOF (int) = 4 bytes; at this time, the members variables of the entire structure have allocated space, the total occupied space size is: 8 1 3 4 = 16 , Just a multiplication of the number of bytes boundaries (ie, the number of bytes occupying the maximum space occupying the maximum space), so no vacant bytes need to be filled. So the size of the entire structure is: sizeof (mYStruct) = 8 1 3 4 = 16, where there are 3 bytes of VC automatically filled, no meaningful things.
Let's take an example below to exchange the position of the member variables of the above MyStruct, so that it becomes the following:
Struct MyStruct
{
Char DDA;
Double DDA1;
Int Type
}
What is the space occupied by this structure? In a VC6.0 environment, SIZEOF (MyStruc) can be obtained. In conjunction with some of the principles of the allocation space mentioned above, how how the VC is allocated to the above structure. (Brief description)
Struct MyStruct
{
Char DDA; // Offset is 0, satisfying alignment, DDA occupies 1 byte;
Double DDA1; / / The offset of the next available address is 1, not sizeof (double) = 8
// The multiple, it is necessary to make up 7 bytes to make the offset be 8 (satisfied alignment)
// mode), so the VC automatically fills 7 bytes, and the DDA1 is stored in the offset of 8.
// The address is on, it takes 8 bytes.
INT TYPE; / / The offset of the next available address is 16, which is the multiplier of sizeof (int) = 4
// Number, meet int gaze, so you don't need VC automatic fill, Type
// On the address of the offset 16, it occupies 4 bytes.
}; // All member variables are allocated, the total size is 1 7 8 4 = 20, not structure
// The number of bounds (ie, the number of bytes occupying the maximum space in the structure) SIZEOF
// (Double) = 8) The multiple of the number, so you need to fill 4 bytes to meet the size of the structure to // sizeOf (double) = 8 multiple.
So the total size of this structure is: sizeof (mYStruc) is 1 7 8 4 4 = 24. The total 7 4 = 11 bytes are VC automatic filled, and there is no meaningful thing.
The special processing of the VC to the structure does increase the speed of the CPU storage variable, but sometimes it brings some trouble, we also mask the default alignment of the variable, you can set the alignment of the variable.
#Pragma pack (n) is provided in the VC to set the variable to align in the n-byte alignment. N-byte alignment is that there are two cases of the offset of the start addresses of the variable storage: First, if n is greater than or equal to the number of bytes occupied by this variable, the offset must meet the default alignment, second If N is less than the number of bytes occupied by the type of the variable, then the offset is a multiple of N, which does not need to satisfy the default alignment. The total size of the structure also has a constraint condition, divided into two cases: If n is greater than the number of bytes occupied by all member variable types, the total size of the structure must be a multiple of the number of space occupied by the maximum space of space;
Otherwise, the multiple must be n. The following is an example of its usage.
#pragma pack (push) // Save the alignment status
#pragma pack (4) // Set to 4 bytes alignment
Struct Test
{
Char m1;
Double M4;
INT M3;
}
#pragma pack (pop) // Restore alignment status
The size of the above structure is 16, and the storage case is analyzed below. First, the m1 allocation space, the offset is 0, satisfying the alignment of our own settings (4 bytes alignment), and M1 take up one byte. Then start to allocate space for the M4. At this time, its offset is 1, which requires complement of 3 bytes, which makes the offset multiple multiple of N = 4 (because sizeof (double is greater than n), M4 occupies 8 words Section. Then, the m3 allocation space, then its offset is 12, the number of four is satisfied, and the m3 occupies 4 bytes. At this time, it has been assigned a space for all member variables, allocated 16 bytes, satisfying a multiple of n. If we change the top #pragma pack (4) to #pragma Pack (16), then we can get the size of 24. (Please analyze your own yourself)
2, SIZEOF usage summary
In VC, SizeOf has a lot of usage and it is easy to cause some errors. The following is summarized according to the parameters behind SizeOf.
A. The parameter is a data type or is a general variable. For example, SizeOf (int), SizeOf (long), etc. This situation should be noted that the results obtained by different system systems or different compilers may be different. For example, the int type accounts for 2 bytes in the 16-bit system, and 4 bytes in the 32-bit system.
B. The parameter is an array or a pointer. The following is an example.
INT A [50]; // sizeof (a) = 4 * 50 = 200; the space size of the number of groups
INT * a = new int [50]; // sizeof (a) = 4; A is a pointer, SIZEOF (a) is a pointer
// Size, in the 32-bit system, of course, 4 bytes.
C. The parameter is a structure or class. The SIZEOF application is the same in the processing of classes and structures. However, there are two points to note that static members in the first, structural or class do not affect the size of the structure or class, as the storage location of the static variable is independent of the instance address of the structure or class.
Second, there is no size of the structure or class of a member variable is 1, because each of the structures or classes must be guaranteed
An instance has a unique address in memory. Below will now be described,
Class test {Int a; static double c}; // sizeof (test) = 4.
Test * s; // sizeof (s) = 4, S is a pointer.
Class test1 {}; // sizeof (test1) = 1;
D. The parameter is other. The following is an example.
Int Func (Char S [5]);
{
The parameters of cout / The system is processed as a pointer when passing.
// In actually the size of the pointer is actually in sizeof (s).
Return 1;
}
SIZEOF (FUNC ("1234")) = 4 // Because the return type of FUNC is int, it is equivalent to
// Ask SIZEOF (int).
The above is the basic usage of SIZEOF, pay attention to the assignment strategy of the allocation variable of VC in practice, so that some errors can be avoided.