Deep Analysis of sizeof () mona1 functions in C Language)

Source: Internet
Author: User
Tags microsoft c

Deep Analysis of sizeof () mona1 functions in C Language)
Finishing by: Yu Chao EMAIL: yuchao86@gmail.com

I. sizeof Concept
Sizeof is a type of single object operator in C language, such as other operators ++ and -- in C language. It is not a function. The sizeof operator provides the storage size of its operands in bytes. The operand can be an expression or a type name enclosed in parentheses. The storage size of the operands is determined by the type of the operands.
Ii. Usage of sizeof
1. Used for Data Types
Sizeof usage: sizeof (type)
The data type must be enclosed in parentheses. For example, sizeof (int ).
2. Used for variables
Sizeof format: sizeof (var_name) or sizeof var_name
Variable names can be enclosed in parentheses. For example, sizeof (var_name) and sizeof var_name are all in the correct format. Brackets are more commonly used. Most programmers use this form.
Note: the sizeof operator cannot be used for function types, which are incomplete types or bit fields. An incomplete data type refers to a data type with an unknown storage size, such as an array type with an unknown storage size, an unknown content structure, a union type, and a void type.
For example, if sizeof (max) is defined as int max () and sizeof (char_v), if char_v is defined as char char_v [max] and MAX is unknown, sizeof (void) are not in the correct format.
First look at an instance:
[Yuchao @ yuchao-Latitude-E5410 scons] $ cat hello. c
# Include <stdio. h>
Struct struct_a {
Char;
Int B;
Short c;
} St_a;
Struct struct_ B {
Int e;
Char f;
Short g;
} St_ B;

Int
Main (int argc, char * argv [])
{
Int num;
Unsigned int num1;

Char char1;
Short st;
Float fl;
Double db;

Printf ("the char sizeof is: % d \ n", sizeof (char1 ));
Printf ("the short sizeof is: % d \ n", sizeof (st ));
Printf ("the int sizeof is: % d \ n", sizeof (num ));
Printf ("the unsigned int sizeof is: % d \ n", sizeof (num1 ));
Printf ("the float sizeof is: % d \ n", sizeof (fl ));
Printf ("the double sizeof is: % d \ n", sizeof (db ));
Printf ("the struct point = % d \ n", sizeof (st_a ));
Printf ("the B struct point = % d \ n", sizeof (st_ B ));
}
The running result is as follows: the compiler performs alignment on the struct.
[Yuchao @ yuchao-Latitude-E5410 scons] $./Hello
The char sizeof is: 1
The short sizeof is: 2
The int sizeof is: 4
The unsigned int sizeof is: 4
The float sizeof is: 4
The double sizeof is: 8
The struct point = 12
The B struct point = 8
[Yuchao @ yuchao-Latitude-E5410 scons] $
Iii. sizeof results
The result type of the sizeof operator is size_t, which is in the header file
Typedef is of the unsigned int type. This type ensures that it can accommodate the maximum object size.
1. If the operand has a char, unsigned char, or signed char type, the result is equal to 1.
Ansi c officially specifies that the character type is 1 byte.
2. int (2), unsigned int (2), short int (2), unsigned short (2), long int (4), unsigned long (4), float (4), double (8), long double (10) type sizeof no specific provisions in ansi c, the size depends on the implementation, generally, they may be 2, 2, 2, 4, 4, 4, 8, or 12.
3. When the operand is a pointer, sizeof depends on the compiler. For example, in Microsoft C/C ++ 7.0, the number of near class pointers is 2, and the number of far and huge class pointers is 4. Generally, the number of Unix pointer bytes is 4.
4. When the operand has an array type, the result is the total number of bytes of the array.
5. the sizeof of the Union type operand is the maximum number of bytes of its member. The sizeof of the Structure Type operand is the total number of bytes of this type of object, including any padding.
Let's look at the following structure:
Struct {char B; double x;};
On some machines, sizeof (a) = 12, while generally sizeof (char) + sizeof (double) = 9.
This is because when the compiler considers alignment, it inserts vacancies in the structure to control the address alignment of each member object. For example, the double-type structure member x should be placed in the address divisible by 4. (Sizeof (char) (4) + sizeof (double) (8) = 12;
6. If the operand is an array parameter in the function or a function-type parameter, sizeof gives the pointer size.
Iv. Relationship between sizeof and other operators
The priority of sizeof is Level 2, which is higher than Level 3 operators such as/and %. It can be used together with other operators to form an expression. For example, I * sizeof (int); where I is an int type variable. (*,/, % is? Level operators)
V. main use of sizeof
1. One major purpose of the sizeof operator is to communicate with routines such as storage allocation and I/O systems. For example:
Void * malloc (size_t size ),
Size_t fread (void * ptr, size_t size, size_t nmemb, FILE * stream ).
2. Another major purpose of sizeof is to calculate the number of elements in the array. For example:
Void * memset (void * s, int c, sizeof (s )).
(Memsetsrc refers to the memory area. Copy count bytes to the memory area indicated by dest ..
Memcpy is used for memory copying. You can use it to copy any data type object)
Vi. Suggestions
Because the number of bytes of the operand may change during implementation, we recommend that you use sizeof to replace constant calculation when it comes to the size of the operand bytes.
This article consists of two parts. The first part focuses on how to use sizeof in VC to find the structure size and problems that are prone to, and provides solutions to the problems, the second part summarizes the main usage of sizeof in VC.
1. Structure of sizeof applications
See the following structure:
 
Struct MyStruct
{
Double dda1;
Char dda;
Int type
};
What will happen if sizeof is used for the structure MyStruct? What is sizeof (MyStruct? You may ask:
Sizeof (MyStruct) = sizeof (double) + sizeof (char) + sizeof (int) = 13
However, when the above structure is tested in VC, you will find that sizeof (MyStruct) is 16. Do you know why such a result is obtained in VC?
In fact, this is a special processing of variable storage by VC. To increase the CPU storage speed, VC performs "alignment" on the starting addresses of some variables. By default, VC specifies that the offset of the starting address of each member variable to the starting address of the structure must be a multiple of the bytes occupied by the variable type. Common alignment types are listed below (vc6.0, 32-bit system ).
Type
Alignment (offset of the starting address of the variable to the starting address of the structure)
Char
The offset must be a multiple of sizeof (char), that is, 1.
Int
The offset must be a multiple of sizeof (int), that is, 4.
Float
The offset must be a multiple of sizeof (float), that is, 4.
Double
The offset must be a multiple of sizeof (double), that is, 8.
Short
The offset must be a multiple of sizeof (short), that is, 2.
When each member variable is stored, the space is requested in sequence based on the order in which the structure appears, and the positions are adjusted according to the alignment above. The vacant byte VC is automatically filled. At the same time, to ensure that the size of the structure is a multiple of the number of byte boundary values of the structure (that is, the number of bytes occupied by the Type occupying the maximum space in the structure, therefore, after applying for space for the last member variable, the vacant bytes will be automatically filled as needed.
The following uses the previous example to illustrate how VC stores the structure.
Struct MyStruct
{
Double dda1;
Char dda;
Int type
};
When allocating space for the above structure, VC allocates space for the first member dda1 according to the sequence and alignment of the member variables, the starting address is the same as the starting address of the structure (the offset 0 is just a multiple of sizeof (double). The member variable occupies eight bytes; next, allocate space for the second member DDA. the offset of the next address that can be allocated to the starting address of the structure is 8, which is a multiple of sizeof (char, therefore, the DDA is stored in an alignment where the offset is 8. This member variable occupies sizeof (char) = 1 byte, and then allocates space for the third member type, in this case, the offset of the next allocable address to the starting address of the structure is 9, not a multiple of sizeof (INT) = 4. To meet the offset constraints of alignment, VC automatically fills in three bytes (these three bytes do not have anything). At this time, the next address that can be allocated has a 12 offset to the starting address of the structure, which is exactly sizeof (INT) = a multiple of 4, so the type is stored in the place where the offset is 12. This member variable occupies sizeof (INT) = 4 bytes; at this time, the member variables of the entire structure have been allocated space. The total occupied space is 8 + 1 + 3 + 4.
= 16, which is a multiple of the bytes boundary of the structure (that is, the number of bytes occupied by the Type occupying the maximum space in the structure sizeof (double) = 8, therefore, no vacant bytes need to be filled. Therefore, the size of the entire structure is sizeof (mystruct) = 8 + 1 + 3 + 4 = 16. Among them, three bytes are automatically filled by VC and nothing makes sense.
Next, let's take another example to change the position of the member variable of mystruct above to the following:
Struct mystruct
{
Char DDA;
Double dda1;
Int type
};
How much space does this structure occupy? In the vc6.0 environment, we can obtain that sizeof (mystruc) is 24. Based on the space allocation principles mentioned above, we will analyze how VC allocates space for the above structure. (Simple description)
Struct mystruct
{
Char dda; // The offset is 0. The alignment is satisfied and the dda occupies 1 byte;
Double dda1; // the offset of the next available address is 1, not sizeof (double) = 8
// Multiple. You need to add 7 bytes to make the offset 8 (the alignment is satisfied ).
// Method). Therefore, VC automatically fills in 7 bytes, and dda1 is stored at an offset of 8
// Address, which occupies 8 bytes.
Int type; // the offset of the next available address is 16, which is twice that of sizeof (int) = 4.
// Number, which meets the alignment of int, so no VC auto-fill is required.
// Put the address at the offset of 16, which occupies 4 bytes.
}; // All member variables are allocated space. The total size of the space is 1 + 7 + 8 + 4 = 20, not a structure.
// Number of knots (that is, the number of bytes occupied by the largest space type in the structure sizeof
// (Double) = 8), so four bytes need to be filled to meet the structure size
// Sizeof (double) = a multiple of 8.
Therefore, the total size of this structure is: sizeof (MyStruc) is 1 + 7 + 8 + 4 + 4 = 24. Among them, 7 + 4 = 11 bytes are automatically filled by VC, and nothing makes sense.
The special processing of the structure storage by VC does increase the speed of the CPU storage variable, but sometimes it also brings some trouble. We also shield the default alignment of the variables, you can set the alignment of variables.
# Pragma pack (n) is provided in VC to set the variable to n-byte alignment. N-byte alignment means the offset of the Start address of the variable. First, if n is greater than or equal to the number of bytes occupied by the variable, the offset must meet the default alignment mode, second, if n is less than the number of bytes occupied by the variable type, the offset is a multiple of n, and the default alignment is not required. The total size of the structure also has a constraint, which is divided into the following 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 space occupied by the largest variable;
Otherwise, it must be a multiple of n. The following is an example of its usage.
# Pragma pack (push) // save alignment status
# Pragma pack (4) // set to 4-byte alignment
Struct test
{
Char m1;
Double m4;
Int m3;
};
# Pragma pack (pop) // restore alignment
The size of the above structure is 16. Next we will analyze its storage situation. First, we will allocate space for m1, and its offset is 0, which meets our own alignment (4-byte alignment ), m1 occupies 1 byte. Then we start to allocate space for m4. At this time, the offset is 1 and three bytes need to be supplemented. In this way, the offset must be a multiple of n = 4 (because sizeof (double) is greater than n ), m4 occupies 8 bytes. Then allocate space for m3. At this time, the offset is 12, which must be a multiple of 4. m3 occupies 4 bytes. At this time, space has been allocated for all member variables. A total of 16 bytes are allocated, which is a multiple of n. If you change # pragma pack (4) to # pragma pack (16), the size of the structure is 24. (Please analyze it by yourself)
2. sizeof usage Summary
In VC, sizeof has many usage and may cause some errors. Next, we will summarize the usage of sizeof based on the parameters following sizeof.
A. the parameter is A data type or A common variable. For example, sizeof (int) and sizeof (long. In this case, it should be noted that the results of different system systems or compilers may be different. For example, the int type occupies 2 bytes in a 16-bit system and 4 bytes in a 32-bit system.
B. the parameter is an array or pointer. The following is an example.
Int a [50]; // sizeof (a) = 4*50 = 200; calculates the space occupied by the array.
# Int * a = "hello world", which should be 12 (note)
Int * a = new int [50]; // sizeof (a) = 4; a is a pointer, and sizeof (a) is a pointer.
// The size of a 32-bit system, of course, 4 bytes.
C. The parameter is a structure or class. The processing of Sizeof applications in the class and structure is the same. However, there are two points to note: first, static members in the structure or class do not affect the size of the structure or class, because the storage location of static variables is irrelevant to the instance address of the structure or class.
Second, the structure without member variables or the size of the class is 1, because each instance of the structure or class must have a unique address in the memory.
The following is an example,
Class Test {int a; static double c}; // sizeof (Test) = 4.
Test * s; // sizeof (s) = 4, and s is a pointer.
Class test1 {}; // sizeof (test1) = 1;
D. The parameter is other. The following is an example.
Int func (char s [5]);
{
Cout <sizeof (s) <endl;
// When a number parameter is passed, the system processes it as a pointer
// Calculate the pointer Size Based on sizeof (s.
Return 1;
}
Sizeof (func ("1234") = 4 // because the return type of func is int, it is equivalent
// Calculate sizeof (int). Note that "1234" instead of "12345 ")
The above is the basic usage of sizeof. In actual use, pay attention to the analysis of the allocation policy of VC allocation variables, so as to avoid some errors.

Related Article

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.