The determination of the size of the structure by sizeof

Source: Internet
Author: User

typedef struct
{
int A;
Char b;
}a_t;
typedef struct
{
int A;
Char b;
char c;
}b_t;
typedef struct
{
Char A;
int b;
char c;
}c_t;
void Main ()
{
char*a=0;
Cout<<sizeof (a) <<ENDL;//4
Cout<<sizeof (*a) <<endl;//1--This can understand
Cout<<sizeof (a_t) <<ENDL;//8
Cout<<sizeof (b_t) <<ENDL;//8
Cout<<sizeof (c_t) <<ENDL;//12
}
Why is this the result?


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;




5. sizeof for pointer variables
Since it is to store the address, it certainly equals the width of the internal address bus of the computer. So in a 32-bit computer, a

The return value of a pointer variable must be 4 (in bytes), which can be expected in a future 64-bit system

The sizeof result in pointer variable 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 the pointer variable has nothing to do with the object that the pointer refers to, because all the pointer variables occupy memory

are equal in size, so the MFC message processing function uses two parameters wparam, LPARAM can pass a variety of complex message knot

Use 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 there is a null terminator at the end of the string
sizeof (A2); Result is 3*4=12 (dependent on int)
Some friends started with sizeof as the number of array elements, and now you should know it's not right, that

How should we find the number of array elements? Easy, usually has the following two kinds of wording:
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, the following C3,C4 value should be how much?
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

Array type, instead of transforming into pointers, equivalent to char* A3, why? Think it over and it's easy to understand that we call

When the function foo1, will the program allocate an array of size 3 on the stack? No! The array is "transmitted", and the caller

Simply pass the address of the argument to the past, so A3 is naturally the pointer type (char*), and the C3 value 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 look at a structure first:


struct S1
{
char c;
int i;
};
Q. How much does sizeof (S1) equal? Smart you start thinking, Char takes 1 bytes, int is 4 bytes, then add

It's supposed to be 5. Is that right? Have you tried it on your machine? Maybe you're right, but you're probably wrong! V

The result of the default setting in C6 is 8.
Why? Why is it always me that hurts?
Please don't be upset, 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 the memory allocations for S1:
S1 S1 = {A, 0xFFFFFFFF};
After defining the above variables, add breakpoints, run the program, observe the memory where the S1 is located, what do 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
What did you find out? How is the 3-byte cc in the middle? Check out the instructions on MSDN:
When applied to a structure type or variable, sizeof returns the actual size,

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 alignment? The principle of computer composition teaches us that this helps to speed up the number of computers, otherwise

You have to spend more time on the instruction cycle. To do this, the compiler handles the structure by default (in fact the data in other places is changed

), the base data type (short, etc.) with a width of 2 is located at an address divisible by 2, allowing the width

The basic data type of 4 (int, etc.) is located on an address that is divisible by 4, and so on. In this way, the middle of the two-digit

Padding bytes may need to be added, so the sizeof value of the entire struct is increased.
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 is 8? Look at the memory again, the original member C still has 3 filler words behind

section, which is why AH? Don't worry, summarize the rules below.

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 offsets (offset) of each member of the struct relative to the first address of the struct are an integer multiple of the member size, if any

Requires the compiler to add padding bytes (internal adding) between members;
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

Member and then add padding bytes (trailing padding).
For the above guidelines, there are a few things to note:
1) The first is not to say that the address of a struct member is an integer multiple of its size, how is it said that the offset amount? Because with the first

1 points exist, so we can just 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 is also

Stddef.h is defined in the following:
#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,

As another struct, so when looking for the widest base type member, you should include the child members of the compound type member,

Instead of seeing composite members as a whole. However, when determining the offset position of a composite type member, the composite type

As a whole view.
Here is a bit of a mouthful, thinking is also a bit scratching their heads, or let us take a look at the example (the exact value is still VC

6 For example, no longer explained later):
struct S3
{
Char C1;
S1 s;
Char C2
};
The type of the widest simple member of the S1 is int,s3 to "break" the S1 when considering the widest simple type member, so

The widest simple type of S3 is int, so that a variable defined by S3 needs to be divisible by 4 for the first address of the storage space, the entire

The value of a sizeof (S3) should also be divisible by 4.
Is the offset of the C1 0,s? At this point S is a whole, and as a struct variable also satisfies the previous three criteria

, so its size is 8, the offset is between 4,C1 and s needs 3 padding bytes, and C2 and s no need,

So the C2 offset is 12, the size of the C2 is 13,13 can not be divisible by 4, so the end of the 3 fill

byte-filling. 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 (trail

ing padding)

Here, friends should have a whole new understanding of the structure of sizeof, but do not be happy too early, there is a

The important parameters affecting sizeof have not been mentioned, which is the compiler's pack instructions. It is used to adjust the alignment of the structure body

, different compiler names and usages are slightly different, implemented by #pragma pack in VC6, and can be modified directly

/ZP the compile switch. The basic usage of #pragma pack is: #pragma pack (n), n is a byte-aligned number, and its 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 member's offset

The amount should be based on this value, that is, the structure member of the offset should take the minimum value, 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 the offset of I is 2, plus sizeof (i) equals

6, can be divisible by 2, so the size of the whole S1 is 6.
Similarly, for sizeof (S3), the offset of S to 2,C2 is 8, plus sizeof (C2) equals 9, cannot be

2 is divisible, adding a padding byte, so sizeof (S3) equals 10.
Now, friends can easily breathe out,

It is also important to note that the size of the "empty struct" (without data members) is not 0, but 1. Imagine a "not accounted for

How can the variable of space "be taken address, two different" empty struct "variables be distinguished? So, "

An empty struct "variable is also stored so that the compiler can allocate only one byte of space for the placeholder.

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 struct with the bit field.

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 to allow

Other types of type exist.
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, the following field will

Adjacent to the previous field store until it cannot be accommodated;
2) If the adjacent bit field field has the same type, but its bit width is greater than the type sizeof size, then the following field will

Starting from the new storage unit, its offset is an integer multiple of its type size;
3) If there are different types of adjacent bit field fields, the specific implementation of each compiler will differ, VC6 take the non-compression method

, dev-c++ adopt 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 can only

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

The Fit sizeof is the maximum value of each member sizeof. A member of a struct can also be a composite type, here,

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;
};

The determination of the size of the structure by sizeof

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.