Deep Analysis of sizeof in C Language

Source: Internet
Author: User

1) parsing sizeof in C Language

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.

Iii. sizeof results
The result type of the sizeof operator is size_t. 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. the sizeof types of int, unsigned int, short int, unsigned short, long int, unsigned long, float, double, and long double are not specified in ansi c, the size depends on the implementation, which may be 2, 2, 2, 4, 4, 4, 8, or 10.

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.

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.

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 )).

Vi. Suggestions
Since the number of bytes of the operand may change during implementation, we recommend that you use ziseof to replace constant calculation when it comes to the size of the operand bytes.

 

2) sizeof
Pascal's memory capacity measurement function:
Usage:
VaR
A: array [1 .. 10000] of longint;
Begin
Writeln (sizeof ());
End.
Output: 40000
If integer is defined, the output is 20000.
Determine the Data Type length in C Language
Usage
Sizeof (type specifier, array name or expression );
Or
Sizeof variable name
1. Definition:
Sizeof is an operator in C/C ++. In short, sizeof is used to return the memory bytes occupied by an object or type.
The description on msdn is as follows:
The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type (including aggregate types). This keyword returns a value of Type size_t.
The return value type is size_t, which is defined in the header file stddef. h. This is a value dependent on the compilation system, which is generally defined
Typedef unsigned int size_t;
Compilers in the world are widely used, but as a specification, they all guarantee char, signed Char, and unsigned
The sizeof value of char is 1. After all, char is the smallest data type that can be programmed.
2. Syntax:
Sizeof has three syntax forms:
1) sizeof (object); // sizeof (object );
2) sizeof (type_name); // sizeof (type );
3) sizeof object; // sizeof object;
So,
Int I;
Sizeof (I); // OK
Sizeof I; // OK
Sizeof (INT); // OK
Sizeof int; // Error
Since writing 3 can be replaced by writing 1, in order to unify the form and reduce the burden on our brains, there are 3rd writing methods. Forget it! In fact, the size of the sizeof calculation object is also converted to the calculation of the object type, that is, the sizeof values of different objects of the same type are consistent. Here, the object can be further extended to the expression, that is, sizeof can evaluate an expression. The Compiler determines the size based on the final result type of the expression, and generally does not calculate the expression. For example:
Sizeof (2); // The type of 2 is int, so it is equivalent to sizeof (INT );
Sizeof (2 + 3.14); // The type of 3.14 is double, and 2 is also upgraded to double, so it is equivalent to sizeof (double );
Sizeof can also be used to evaluate a function call. The result is the size of the function return type, and the function is not called. Let's take a complete example:
Char Foo ()
{
Printf ("Foo () has been called./N ");
Return 'a ';
}
Int main ()
{
Size_t SZ = sizeof (FOO (); // the return value type of Foo () is Char, so SZ = sizeof (char), Foo () is not called
Printf ("sizeof (FOO () = % d/N", SZ );
}
According to the c99 standard, functions, expressions of undetermined types, and bit-field members cannot be computed with sizeof values. That is, the following statements are incorrect:
Sizeof (FOO); // Error
Void foo2 (){}
Sizeof (foo2 (); // Error
Struct s
{
Unsigned int F1: 1;
Unsigned int F2: 5;
Unsigned int F3: 12;
};
Sizeof (S. F1); // Error
3. constants of sizeof
The sizeof calculation occurs at the Compilation Time, so it can be used as a constant expression, such:
Char ary [sizeof (INT) * 10]; // OK
The latest c99 standard stipulates that sizeof can also be calculated at runtime. The following programs can be correctly executed in Dev-C ++:
Int N;
N = 10; // n Dynamic assignment
Char ary [N]; // c99 also supports dynamic definition of Arrays
Printf ("% d/N", sizeof (ary); // OK. Output 10
But it won't work in the compiler that does not fully implement the c99 standard, and the above Code won't be able to compile in vc6. Therefore, we 'd better think that sizeof is executed during the compilation period. This will not cause errors and make the program more portable.
4. sizeof of basic data type
The basic data types here refer to simple built-in data types such as short, Int, long, float, and double. Because they are all related to the system, the values may be different in different systems, this must attract our attention, and try not to cause trouble for porting our programs in this respect.
Generally, in a 32-bit compiling environment, the value of sizeof (INT) is 4.
5. sizeof pointer variable
If you have learned the data structure, you should know that the pointer is a very important concept, which records the address of another object. Since the address is stored, it is equal to the width of the computer's internal address bus. Therefore, in a 32-bit computer, the return value of a pointer variable must be 4 (note that the result is in bytes), which can be predicted, in the future 64-bit system, the sizeof result of the pointer variable is 8.
Char * Pc = "ABC ";
Int * PI;
String * pS;
Char ** PPC = & PC;
Void (* PF) (); // function pointer
Sizeof (PC); // The result is 4
Sizeof (PI); // The result is 4
Sizeof (PS); // The result is 4
Sizeof (PPC); // The result is 4
Sizeof (PF); // The result is 4
The sizeof value of the pointer variable has nothing to do with the object indicated by the pointer. It is precisely because all pointer variables occupy the same memory size, therefore, the MFC message processing function uses two parameters wparam and lparam to transmit various complex message structures (using pointers to struct ).
6. sizeof of Array
The sizeof value of the array is equal to the number of memory bytes occupied by the array, for example:
Char A1 [] = "ABC ";
Int A2 [3];
Sizeof (A1); // The result is 4. A null Terminator exists at the end of the character.
Sizeof (A2); // The result is 3*4 = 12 (dependent on INT)
Some friends regard sizeof as the number of array elements at the beginning. Now, you should know that this is not correct. How should we calculate the number of array elements easily, there are usually two ways to write:
Int C1 = sizeof (A1)/sizeof (char); // total length/length of a single element
Int C2 = sizeof (A1)/sizeof (A1 [0]); // total length/length of the first element
Write it here and ask, what is the value of C3 and C4 below?
Void foo3 (char A3 [3])
{
Int C3 = sizeof (A3); // C3 =
}
Void foo4 (char A4 [])
{
Int C4 = sizeof (A4); // C4 =
}
Maybe when you try to answer the C4 value, you realize that C3 is wrong. Yes, C3! = 3. Here, the function parameter A3 is no longer an array type, but a pointer, which is equivalent to char * A3. It is hard to understand why, when we call the function foo1, will the program allocate a 3 array on the stack? No! The array is "Address Transfer". The caller only needs to pass the address of the real parameter, so A3 is naturally a pointer type (char *), and the C3 value is 4.
7. sizeof of struct
This is the most frequently asked question for beginners, so it is necessary to pay more attention here. Let's first look at a struct:
Struct S1
{
Char C;
Int I;
};
Ask how smart the sizeof (S1) is. You start to think about it. Char occupies 1 byte and INT occupies 4 byte. Then, the total value should be 5. Is that true? Have you tried it on your machine? Maybe you are right, but you are probably wrong! In vc6, the default value is 8.
Why is my injury always me?
Don't be frustrated. Let's take a look at the definition of sizeof. The result of sizeof is equal to the number of memory bytes occupied by the object or type. Well, let's take a look at the memory allocation of S1:
S1 S1 = {'A', 0 xffffffff };
After defining the above variables, add breakpoints, run the program, and observe the memory where S1 is located. what do you find?
Take my vc6.0 as an example. The S1 address is 0x0012ff78, and its data content is as follows:
0012ff78: 61 CC FF
What are the three-byte CC in the middle? Let's take a look at the description on msdn:
When applied to a structure type or variable, sizeof returns the actual size, which may include Padding Bytes inserted for alignment.
Originally, this is the legendary byte alignment! An important topic has emerged.
Why do we need byte alignment principles to teach us how to speed up the computer's data acquisition speed? Otherwise, it will take a longer command cycle. For this reason, the compiler will process the struct by default (in fact, the data variables in other places are also the same), so that the basic data type with a width of 2 (short, etc) are located on the address that can be divisible by 2, so that the basic data type (INT, etc.) with the width of 4 is located on the address that can be divisible by 4, and so on. In this way, the two numbers may need to be added to the padding byte, so the sizeof value of the entire struct increases.
Let's exchange the positions of char and INT in S1:
Struct S2
{
Int I;
Char C;
};
Let's look at the number of sizeof (S2) results. How can we still look at the memory at 8? The original member C still has three Padding Bytes. Why? Don't worry. The following summarizes the rules.
The details of byte alignment are related to compiler implementation, but generally three criteria are met:
1) The first address of the struct variable can be divisible by the size of its widest basic type member;
2) The offset (offset) of each member of the struct to the first address of the struct is an integer multiple of the member size. If necessary, the compiler will add the internal adding between the members );
3) the total size of the struct is an integer multiple of the size of the widest basic type of the struct. If necessary, the compiler will add the trailing padding after the last member ).
There are several notes for the above principles:
1) I didn't mean that the address of a struct member is an integer multiple of its size. How can I talk about the offset? Because a 1st point exists, we can only consider the member offset, this is easy to think about. Think about why.
The offset of a member of the struct to the first address of the struct can be obtained through the macro offsetof (). This macro is also defined in stddef. H, as follows:
# Define offsetof (S, m) (size_t) & (S *) 0)-> m)
For example, to get the offset of C in S2, the method is
Size_t Pos = offsetof (S2, c); // POS equals 4
2) The basic type refers to the built-in data types such as char, short, Int, float, and double mentioned above. The "data width" here refers to the size of its sizeof. Because the struct member can be a composite type, for example, another struct, when looking for the widest basic type member, it should include the Child Member of the composite type member, instead of seeing a composite member as a whole. However, when determining the offset of a composite member, the composite type is regarded as a whole.
This is a bit difficult to describe here, and it seems a bit confusing to think about it. Let's take a look at the example (the specific value is still taken as an example of vc6 and will not be explained later ):
Struct S3
{
Char C1;
S1 S;
Char C2;
};
The type of the widest and simplest member of S1 is int. When considering the widest and simplest type members, S3 splits S1, so the widest and simplest type of S3 is int. In this way, for variables defined by S3, the first address of the bucket needs to be divisible by four, and the entire sizeof (S3) value should also be divisible by four.
The offset of C1 is 0, and the offset of S is a whole. As a struct variable, S satisfies the preceding three criteria, so its size is 8 and its offset is 4, three bytes are required between C1 and S, and the offset between C2 and S is 12, the size of C2 is 13, and 13 cannot be fully divided by 4. Therefore, three fill bytes must be added at the end. Finally, the value of sizeof (S3) is 16.
Through the above description, we can get a formula:
The size of the struct is equal to the offset of the last member plus the size of the struct plus the number of filled bytes at the end, that is:
Sizeof (struct) = offsetof (last item) + sizeof (trailing padding)
Here, friends should have a new understanding of the sizeof struct, but don't be too happy. An important parameter that affects sizeof has not been mentioned yet, that is the pack instruction of the compiler. It is used to adjust the structure alignment mode. Different compiler names and usages are slightly different. In vc6, the # pragma pack is used for implementation, and you can also directly modify the/ZP compilation switch. # Basic usage of The Pragma Pack: # pragma pack (N), where N is the number of bytes alignment. The default value is 8, if this value is smaller than the sizeof value of the struct
The offset of the member should take this value as the standard, that is, the offset of the struct member should take the minimum value of the two,
The formula is as follows:
Offsetof (item) = min (n, sizeof (item ))
Let's look at the example:
# Pragma pack (push) // Save the current pack setting pressure Stack
# Pragma pack (2) // must be used before struct Definition
Struct S1
{
Char C;
Int I;
};
Struct S3
{
Char C1;
S1 S;
Char C2;
};
# Pragma pack (POP) // restore previous pack settings
When sizeof (S1) is calculated, the value of min (2, sizeof (I) is 2, so the offset of I is 2, and the value of sizeof (I) is 6, it can be divisible by 2, so the size of the entire S1 is 6.
Similarly, for sizeof (S3), the offset of S is 2, the offset of C2 is 8, and the addition of sizeof (C2) is equal to 9, cannot be divisible by 2, add a fill byte, so sizeof (S3) is equal to 10.
Now, friends can breathe a sigh of relief ,:)
Note that the size of the "Empty struct" (excluding data members) is not 0, but 1. Imagine how a variable with "no space occupied" can be separated by an address and two different "Empty struct" variables. Therefore, the variable "Empty struct" must also be stored, in this way, the compiler can only allocate one byte of space for occupying space. As follows:
Struct S5 {};
Sizeof (S5); // The result is 1.
8. sizeof containing bitfield struct
As mentioned above, bitfield members cannot be individually sizeof values. Here we will discuss the sizeof of struct containing the bitfield, but specifically list it in consideration of its particularity.
C99 specifies that int, unsigned int, and bool can be used as bit domain types, but almost all compilers have extended these types to allow the existence of other types. The main purpose of bit domains is to compress storage. The general rules are as follows:
1) if the types of adjacent fields are the same, and the sum of the bit widths is smaller than the sizeof size of the type, the subsequent fields will be stored next to the previous field until they cannot be accommodated;
2) If the Field Types of adjacent bit fields are the same, but the sum of Bit Width is greater than the sizeof size of the type, the subsequent fields start from the new storage unit, its offset is an integer multiple of its type;
3) if the types of adjacent bit field are different, the implementations of each compiler are different. vc6 adopts the non-compression mode and Dev-C ++ adopts the compression mode;
4) do not compress fields that are interspersed with non-bit fields;
5) the total size of the entire struct is an integer multiple of the size of the widest basic type.
Let's take a look at the example.
Example 1:
Struct bf1
{
Char F1: 3;
Char F2: 4;
Char F3: 5;
};
Its memory layout is:
| _ F1 __|__ F2 __| _ | ____ F3 ___ | ____ |
| _ |
0 3 7 8 1316
The bit field type is Char, and the 1st bytes can only accommodate F1 and F2, so F2 is compressed to 1st bytes, while F3 only
Starting from the next byte. Therefore, the result of sizeof (bf1) is 2.
Example 2:
Struct bf2
{
Char F1: 3;
Short F2: 4;
Char F3: 5;
};
Because the adjacent bit fields have different types, in vc6, sizeof is 6, and in Dev-C ++ is 2.
Example 3:
Struct bf3
{
Char F1: 3;
Char F2;
Char F3: 5;
};
The non-bit field is interspersed in it and will not produce compression. The size obtained in vc6 and Dev-C ++ is 3.
9. sizeof of the Consortium
The struct structure is sequential in the memory structure, while the consortium is overlapping. Each member shares a piece of memory, so the sizeof of the entire consortium is the maximum value of sizeof each member. Struct members can also be composite. Here, composite Members are considered as a whole.
Therefore, in the following example, the sizeof value of U is equal to sizeof (s ).
Union u
{
Int I;
Char C;
S1 S;
};

 

3) usage of sizeof () in C Language

As long as I participate in the software development test (C/C ++), almost all of them will involve the usage of sizeof (). I met it yesterday, and some will, but the real sizeof () I still don't understand the core. I went online today and saw the detailed description of sizeof () When I was bored. Now I will share it with you.

 

----------Sizeof----------------

 

 

Sizeof is generally in the form of: sizeof (object), you can also sizeof var_char, but most programer is used to sizeof (). The object can be an expression or data type name. When the object is an expression, brackets can be omitted. Sizeof is a single-object operator. The operator indicates the number of bytes occupied by an object in the computer memory. Generally, different machines run different objects. Currently, almost all machines are 32-bit and rarely 16-bit, therefore, the exams are generally based on 32-bit Windows and Linux. There are not many data types in C language. 1. integer: Short, Int, long (I have not considered the symbol problem). Generally, in C language, Int Is two bytes, that is, 16 bits, range:-32768-32767, long is 4 bytes in the range of-2 ^ 32---2 ^ 32-1. When sizeof (INT) is run on XP, output 4 will be generated. This is the reason for 32 bits. Sizeof (long) is also 4. as follows: # include "stdio. H"
# Include "string. H"
# Include "stdlib. H"
Int main ()
{
Short int SA = 10;
Int A = 10;
Long LA = 10;
Float F = 20;
Double D = 20;
Char CH = 'C ';
Char STR [] = "ABC ";
Char * P = STR;
Struct STR {
Double D;
Char ch;
Int data;
} Str_wu;
Struct str1 {
Char ch;
Double D;
Int data;
} Str_wu1;
Printf ("sizeof (short): % d/N", sizeof (SA ));
Printf ("sizeof (INT): % d/N", sizeof ());
Printf ("sizeof (long): % d/N", sizeof (LA ));
Printf ("sizeof (float): % d/N", sizeof (f ));
Printf ("sizeof (double): % d/N", sizeof (d ));
Printf ("sizeof (char): % d/N", sizeof (CH ));
Printf ("sizeof (string): % d/N", sizeof (STR ));
Printf ("sizeof (point address): % d/N", sizeof (p ));
Printf ("sizeof (point): % d/N", sizeof (* p ));
Printf ("sizeof (struct): % d/N", sizeof (str_wu ));
Printf ("sizeof (struct): % d/N", sizeof (str_wu1 ));
System ("pause ");
}{
Window. Open ("http://blog.51cto.com/viewpic.php? Refimg = "+ this. SRC)
} 'Src = "http://img1.51cto.com/attachment/200810/200810211224596908046.jpg" border = "0" alt = ""> SO int, short's sizeof results are the same amount. 2. The figure above float, double, and long double of floating point data is not tested (forgot .....) Haha! But it should be 16. 3. For pointers, it is important to differentiate what data the Pointer Points to. The number of bytes it occupies in the memory is its result. For example, the pointer points to a string, which is the length of the string, because a character occupies one byte in memory. If the pointer points to a data structure, the result should be the memory bytes of the structured data. 4. In the above program, Struct STR {
Double D;
Char ch;
Int data;
} Str_wu;
Struct str1 {
Char ch;
Double D;
Int data;
} Str_wu1;

There are two different structures, but the internal elements are the same. They are both double, Int, and Char. The results are different if the order is different. Why? At this time, because vc needs to store data, the specific situation is as follows: Type
Alignment (offset of the starting address of the variable to the starting address of the structure) Char
The offset must be sizeof (char), that is, a multiple of int 1.
The offset must be sizeof (INT), that is, a multiple of 4 float.
The offset must be sizeof (float), that is, a multiple of 4, double.
The offset must be sizeof (double), that is, a multiple of 8.
The offset must be sizeof (short), that is, a multiple of 2, for example, str_wu. When allocating space for the above structure, VC determines the order and alignment of the member variables, allocate space for the first member dda1. The starting address is the same as the starting address of the structure (the offset 0 is just a multiple of sizeof (double). This member variable occupies sizeof (double) = 8 bytes; next, allocate space for the second member DDA. Then, the offset of the next allocable address 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 allocable address offset to the starting address of the structure is 1. 2, which is just a multiple of sizeof (INT) = 4. Therefore, the type is stored in the place with the offset of 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, it is just a multiple of the number of byte boundary values of the structure (that is, the number of bytes occupied by the largest space type in the structure sizeof (double) = 8). Therefore, no vacant bytes need to be filled. Therefore, the size of the entire structure is sizeof (str_wu) = 8 + 1 + 3 + 4 = 16. Among them, three bytes are automatically filled by VC and nothing makes sense. Str_wu1 follows the same principle: sizeof (char) = 1, while 1 is not a multiple of 8, so it is increased to 8, sizeof (double) = 8, the starting address is 16 and 16 is a multiple of sizeof (INT), which can be saved. Therefore, the total number of addresses: sizeof (char) + 7 + sizeof (double) + sizeof (INT) = 20, while 20 is not a multiple of 8 (sizeof (double) = 8 ), therefore, you need to add four addresses, that is, a total of 24. ---------------------- Sizeof is specific. All I know is what the master knows, or what errors I have written. Thank you!

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.