1. Definition:
Where is sizeof? The Divine sizeof is an operator (operator) in C/s + +, which is also, simply speaking,
The number of bytes of memory that is used to return an object or type.
The explanation on MSDN is:
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.
Its return value type is size_t and is defined in the header file stddef.h. This is a value that relies on the compilation system, a
Defined as
typedef unsigned int size_t;
There are a myriad of compilers in the world, but as a specification they guarantee Char, signed char, and unsigned
The sizeof value of char is 1, after all, char is the smallest data type we can program.
2. Syntax:
sizeof has three grammatical forms, as follows:
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 the 3 can be replaced by the wording 1, in order to unify the form and reduce the burden of our brains, the 3rd way of writing, forget
Drop It!
In fact, the size of the sizeof object is also converted to the calculation of the object type, i.e., the same type of
The sizeof values of the different objects are consistent. Here, the object can be further extended to an expression, where sizeof can
Evaluates an expression, the compiler determines the size based on the end-result type of the expression, and generally does not
For calculation. Such as:
sizeof (2);//2 is of type int, so it is equivalent to sizeof (int);
sizeof (2 + 3.14); The type of 3.14 is double,2 also promoted to double type, so the equivalent
to sizeof (double);
sizeof can also evaluate a function call, the result of which is the size of the function return type, and the function is not called
, let's look at 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 () will not be called
printf ("sizeof (foo ()) =%d/n", SZ);
}
C99 standard specifies that functions, expressions that cannot be determined by type, and bit field (Bit-field) members cannot be evaluated s
The izeof value, that is, the following are the wrong wording:
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. The constant nature of sizeof
SizeOf's calculations occur at compile time, so it can be used as a constant expression, such as:
char ary[sizeof (int) * 10]; Ok
The latest C99 standard specifies that sizeof can also be calculated at run time, as the following program can be used in dev-c++
Execute correctly:
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
However, in a compiler that does not fully implement the C99 standard, the above code will not be compiled in VC6.
So we'd better think that sizeof was executed at compile time, so that it would not cause errors and allow the program to be ported
Better sex.
4. SizeOf of the basic data type
The basic data types here are simple built-in data types such as short, int, long, float, double,
Since they are all related to the system, it may be possible to take different values under different systems, which must cause our note
Try not to cause any problems with the transplant of your own program in this regard.
In general, in a 32-bit compilation environment, sizeof (int) takes a value of 4.
5. sizeof for pointer variables
Learning about data structures you should know that pointers are an important concept that records the address of another object. Both
If it is to store the address, it certainly equals the width of the internal address bus of the computer. So on a 32-bit computer,
, the return value of a pointer variable must be 4 (note that the result is in bytes), which can be expected in the future 6
The sizeof result of a pointer variable in a 4-bit system is 8.
char* PC = "ABC";
int* Pi;
string* PS;
char** PPC = &pc;
void (*PF) ();//function pointer
sizeof (PC); Result is 4
sizeof (PI); Result is 4
sizeof (PS); Result is 4
sizeof (PPC); Result is 4
sizeof (PF);//result is 4
The sizeof value of a pointer variable has nothing to do with the object The pointer refers to, precisely because all pointer variables occupy
The MFC message processing function uses two parameters wparam, LPARAM can pass a variety of complex
Structure (using a pointer to the struct body).
6. The sizeof array
The sizeof value of an array is equal to the number of bytes of memory consumed by the array, such as:
Char a1[] = "ABC";
int a2[3];
sizeof (A1); The result is 4, and a null terminator exists at the end of the character
sizeof (A2); Result is 3*4=12 (dependent on int)
Some friends started with sizeof as the number of array elements, now, you should know that this is wrong,
So how do you find the number of elements in an array? Easy, usually with the following two types of notation:
int c1 = sizeof (A1)/sizeof (char); Total length/length of individual elements
int c2 = sizeof (A1)/sizeof (a1[0]); Total length/length of first element
Write here, ask, what is the C3,C4 value 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 C4 's value, you realize that C3 answered wrong, yes, c3!=3. Here the function parameter A3 is no longer
Again the array type, but the transformation into a pointer, equivalent to char* A3, why it is not difficult to think carefully, I
When we call the function foo1, will the program allocate an array of size 3 on the stack? The array is the "address"
, the caller simply passes the address of the argument to the past, so A3 is naturally the pointer type (char*), and the value of C3 is
4.
7. sizeof of the structure
This is a question that beginners ask most, so it is necessary to pay more and more ink. Let's first look at a struct
:
struct S1
{
char c;
int i;
};
Ask sizeof (S1) is equal to how much smart you start to think, char accounted for 1 bytes, int accounted for 4 bytes, then
Add up should be 5. Did you try it on your machine? Maybe you're right, but you're probably wrong.
Of The result of the default setting in VC6 is 8.
Why is it always me that hurts
Please don't be depressed, let's have a good look at the definition of sizeof the result of--sizeof is equal to the object or type
Memory bytes, okay, let's take a look at S1 's memory allocations:
S1 S1 = {' A ', 0xFFFFFFFF};
After defining the above variables, add breakpoints, run the program, observe the memory where the S1 is located, what you find
Take my VC6.0 for example, S1 's address is 0x0012ff78, and its data is as follows:
0012ff78:61 cc CC FF FF FF FF
Find out what's going on in the middle of a 3-byte cc look at the instructions on MSDN:
When applied to a structure type or variable, sizeof returns the actual siz
E, which may include padding bytes inserted for alignment.
So this is the legendary byte alignment! An important topic came up.
Why do I need byte-aligned computer principles to teach us this helps to speed up the number of computers, no
You have to spend more time on the instruction cycle. To do this, the compiler will process the struct by default (in fact the number of other places
The basic data type (short, etc.) with a width of 2 is located at an address that is divisible by 2.
The base data type (int, etc.) with a width of 4 is located on an address that is divisible by 4, and so on. This way, two
In the middle of the number, it is possible to add padding bytes, so the sizeof value of the entire struct increases.
Let's swap the position of char and int in S1:
struct S2
{
int i;
char c;
};
Look at the results of sizeof (S2) how much, how or 8 and then look at the memory, the original member of C still has 3 after filling
Fill the byte, this is why ah don't worry, the following summarizes the law.
Byte alignment details are related to compiler implementations, but in general, three guidelines are met:
1) The first address of a struct variable can be divisible by the size of its widest base type member;
2) The offset (offset) of each member of the struct relative to the first address of the struct is an integer multiple of the member size,
If necessary, the compiler will add padding bytes between members (internal adding);
3) The total size of the struct is an integer multiple of the size of the structure's widest base type member, and if necessary, the compiler will
The last member is followed by a padding byte (trailing padding).
For the above guidelines, there are a few things to note:
1) The first is not to say that the address of the struct member is an integer multiple of its size, why is it said that the offset?
The 1th existence, so we can only consider the offset of the member, so it is simple to think. Think about why.
The offset of a member of a struct relative to the first address of the struct can be obtained by using the macro Offsetof (), which 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 base type refers to the previously mentioned built-in data types such as char, short, int, float, double
, the "data width" here refers to the size of its sizeof. Because a member of a struct can be a composite type
, such as another structure, so when looking for the widest base type member, you should include the child of the compound type member
Members, rather than the composite members as a whole. However, when determining the offset position of a composite type member, the
Composite types as a whole are regarded.
It's a bit of a mouthful here, and it's a little bit scratching your mind, but let's take a look at the example (the exact value is still
VC6, for example, will not be explained later):
struct S3
{
Char C1;
S1 s;
Char C2
};
The type of the widest simple member of the S1 is INT,S3, when considering the widest simple type member, is to "break" the S1 to see,
So the widest simple type of S3 is int, so that a variable defined by S3, whose first address of the storage space needs to be 4 full
In addition, the entire sizeof (S3) value should also be divisible by 4.
The offset of the C1 is the offset of the 0,s. Then S is a whole, which as a struct variable also satisfies the previous three
Criterion, so its size is 8, the offset is between 4,C1 and s requires 3 padding bytes, and C2 and s do not need
To, so the C2 offset is 12, the size of the C2 is 13,13 can not be divisible by 4, so the end has to fill
The 3 padding bytes. Finally, the value of sizeof (S3) is 16.
From the above narrative, we can get a formula:
The size of the struct is equal to the last member's offset plus its size plus the number of padding bytes at the end, namely:
sizeof (struct) = Offsetof (last item) + sizeof (last item) + sizeof (tr
Ailing padding)
Here, friends should have a whole new understanding of the structure of sizeof, but don't be happy too early, there
One important parameter that affects sizeof is not yet mentioned, which is the compiler's pack instruction. It is used to adjust the structure
Body alignment, different compiler names and usages are slightly different, implemented by #pragma pack in VC6, or you can
Modify the/zp compiler switch directly. The basic usage of #pragma pack is: #pragma pack (n), n is byte aligned
The value is 1, 2, 4, 8, 16, the default is 8, if this value is smaller than the sizeof value of the struct member, then
The offset of the member should be based on this value, that is, the offset of the struct member should take the minimum value of both,
The formula is as follows:
Offsetof (item) = MIN (n, sizeof (item))
Look again at the example:
#pragma pack (push)//Save current pack settings to stack
#pragma pack (2)//must be used before structure 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 I has an offset of 2, plus sizeof (i)
equals 6 and can be divisible by 2, so the entire S1 is 6 in size.
Similarly, for sizeof (S3), the offset of S to 2,C2 is 8, plus sizeof (C2) equals 9, cannot
is divisible by 2, adding a padding byte, so sizeof (S3) equals 10.
Now, it's easy for friends to take a breath,:)
It is also important to note that the size of the "empty struct" (without data members) is not 0, but 1. Imagine a "no
How is the variable that occupies the space "to be taken address, two different" empty structure "variable how to differentiate?
, the "empty struct" variable is also stored so that the compiler can allocate only one byte of space for
A bit. As follows:
struct S5 {};
sizeof (S5); Result is 1
8. sizeof with a bit domain structure
As mentioned earlier, bit-domain members cannot be individually taken with the sizeof value, and what we're going to discuss here is the structure with bit fields.
The body of sizeof, only to consider its particularity and specifically listed it.
C99 specifies that int, unsigned int, and bool can be used as bit field types, but almost all compilers extend this.
Allows the existence of other type types.
The primary purpose of using bit fields is to compress the storage, with the following approximate rules:
1) If the adjacent bit field field is of the same type and its bit width is less than the type sizeof size, then the following word
The segment will be stored adjacent to the previous field until it cannot be accommodated;
2) If the neighboring bit field field has the same type, but its bit width is greater than the type sizeof size, then the following word
The segment begins with the new storage unit, and its offset is an integer multiple of its type size;
3) If the adjacent bit field fields are of different types, the specific implementations of each compiler differ, VC6 take the uncompressed side
, dev-c++ adopts compression method;
4) If the bit field fields are interspersed with non-bit field fields, no compression is performed;
5) The total size of the entire struct is an integer multiple of the size of the widest base type member.
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, the 1th byte can only hold the lower F1 and F2, so F2 is compressed into the 1th byte, and F3 only
Can start with the next byte. Thus the result of sizeof (BF1) is 2.
Example 2:
struct BF2
{
Char F1:3;
Short F2:4;
Char F3:5;
};
Due to the different types of neighboring bit fields, the sizeof is 6 in VC6 and 2 in dev-c++.
Example 3:
struct BF3
{
Char F1:3;
char F2;
Char F3:5;
};
Non-bit field fields are interspersed in which no compression is generated, and the size obtained in VC6 and Dev-c++ is 3.
9. SizeOf of the Consortium
Structure in the memory organization is sequential, the union is overlapping, each member shares a piece of memory, so the entire
sizeof, the consortium, is the maximum value of sizeof for each member. A member of a struct can also be a composite type, which
, composite type members are considered as a whole.
So, in the example below, the sizeof value of U equals sizeof (s).
Union U
{
int i;
char c;
S1 s;
};
A detailed description of the C language sizeof function