The C language is no longer afraid of sizeof (struct)

Source: Internet
Author: User

During the interview, programmers often encounter some questions, give a struct, and then sizeof it. What is the value? For example, the following structure is provided: [cpp] struct test {char a; short B; char c; int d ;}; maybe some students who just started learning C language will not hesitate to add the space occupied by each variable in struct. The result is 8. Then the result is wrong. Why? First, Let's print out their addresses. This is the result: a = 0x00000000, B = 0x0000002, c = 0x00000004, d = zero x 00000008. it's strange, as we expected, they are stored in order. This involves a memory arrangement problem: Memory alignment. First, Let's explain why memory alignment is required. This is related to the features of our processor. The bus reads the memory from an even number of bytes. If the memory is arranged in order, the memory address in the short B arrangement should be: 0x00000001, but it needs to occupy two bytes of memory space. If it is to be stored in this memory address, it needs to be read twice, after reading the data, you must splice the memory content to obtain the short variable. If it is stored at the address B = 0x0000002, you only need to read it once and do not need to splice the memory content. Then the variable c starts to be stored after B. The address is 0x00000004, but it only occupies one byte. Similarly, the remaining space cannot be used for storage, however, since the processor reads data from even bytes, why is the starting address of d 0x00000008. Don't worry. Another rule is that a word is 16 bits. If the double-byte (32 bits) operand spans the 4-byte boundary, or a four-character operand that spans the 8-byte boundary is considered unaligned. That is to say, if d is stored from 0x00000006, it will span the boundary of 0x00000008 and divide it by 4. Therefore, it requires two memory reads and writes. Let's look back at short B, which is stored from 0x00000002, but it does not span the 0x00000004 boundary value. You can also give an example: [cpp] # include <iostream> using namespace std; struct test {char a; char B; char c; short d; int e ;}; int main () {struct test t; int x1 = (unsigned int) (void *) & t. a-(unsigned int) (void *) & t; int x2 = (unsigned int) (void *) & t. b-(unsigned int) (void *) & t; int x3 = (unsigned int) (void *) & t. c-(unsigned int) (void *) & t; int x4 = (unsigned int) (void *) & t. d-(unsigned int) (void *) & t; int x5 = (u Nsigned int) (void *) & t. e-(unsigned int) (void *) & t; printf ("a = 0x % p, B = 0x % p, c = 0x % p, d = 0x % p, e = 0x % p ", x1, x2, x3, x4, x5); cin. get () ;}let's see the printed result. The address of d is 0x00000004, because if it is stored from 0x00000003, it spans the border. Another special case is that a char variable is easygoing, because it occupies a byte in a 32-bit processor, so it doesn't mind where it is stored, that is, because it only occupies one byte, it only needs to be read once no matter where it is stored. Let's take an example: [cpp] struct test {short a; char B; char c int d;}: a = 0x00000000, B = 0x0000002, c = 0x00000003, d = 0x00000008. by default, the compiler performs memory alignment on the member data in the structure and stack by default. In this way, the cost of bus operation is reduced by a waste of memory space. Next let's talk about # pragma pack (n) preprocessing. The main function is to change the memory alignment option and perform memory alignment according to the given n Bytes. However, the most important feature of the structure member alignment method is the minimum principle. The rules for alignment of struct members are as follows: Compare the bytes actually occupied in the memory with the n currently set by # pragma pack (n, take the bottom of the column as the alignment of the current member of the struct, but it does not affect the alignment of other struct members. For example: [cpp] # pragma pack (8) struct test_st1 {char a; long B ;}; struct test_st2 {char c; struct test_st1 st1; long d ;}; in the above example, the memory alignment mode is set to 8-byte alignment. Let's take a look at the struct test_st1, where a occupies 1 of the memory size, and compare it with the specified, take the smallest, so the alignment is 1 byte, for member B, because it occupies 4 bytes, and the specified value is 8, the minimum value is the 4-byte alignment, which means that the memory address can be exceeded by 4 and stored next to the address of a to store B, the size of the struct is 8 bytes. Next let's take a look at the struct test_st2. c is itself a byte, so the alignment is 1, while st1 is a structure, so this structure itself is in other structs, what is the Alignment Method? is the size of the struct compared with the given alignment method? No. Its alignment is to compare the memory space occupied by the largest member variable in its member variable with the given value. Then, st1's alignment is 4, its starting address is the place where it can be divisible by 4. For d, because it occupies 8 bytes of memory, its alignment is 8, c and st1 use 12 bytes, therefore, d can be stored from where the memory address can be divisible by 8, so the size of the test_st2 struct is 24. a complete test procedure is provided: [cpp] # include <iostream> using namespace std; # pragma pack (8) struct test_st1 {char a; long B ;}; struct test_st2 {char c; struct test_st1 st1; long d ;}; int main () {struct test_st2 t; int x1 = (unsigned int) (void *) & t. c-(unsigned int) (void *) & t; int x2 = (unsigned int) (void *) & t. st1.a-(unsigne D int) (void *) & t; int x3 = (unsigned int) (void *) & t. st1. B-(unsigned int) (void *) & t; int x4 = (unsigned int) (void *) & t. d-(unsigned int) (void *) & t; printf ("a = 0x % p, B = 0x % p, c = 0x % p, d = 0x % p ", x1, x2, x3, x4); cin. get () ;}you can debug it on your own to see its memory arrangement in the memory.

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.