C language memory address Basics

Source: Internet
Author: User

It is helpful to think about everything in C language from the perspective of computer memory. We can think of computer memory as a byte array. Each address in the memory represents 1 byte. For example, if our computer has 4 K memory, the memory array will have 4096 elements. When talking about a pointer to a storage address, we should be talking about a pointer that stores an element index of the memory array. When a pointer is referenced in reverse order, the value pointed to by the index in the array is obtained. Of course, this is a lie. The management of memory by the operating system is far more complex than that. The memory is not necessarily continuous and may not be processed in order. However, the analogy above is a simple way to discuss the C language memory.

If you are confused about "Pointer", "Address", and "reverse reference", see "5-minute guide to C language Pointers". // Note: There are many translations of "dereferencing". This article uses "reverse references ".

Suppose our computer has 4 kb of memory, and the index of the next open address is 2048. We declare a new character variable.i='a'. When the memory obtained by the variable is placed with its value, and the name of the variable is also associated with the location in the memory, our character I gets a value stored at the location of 2048. This character is single-byte, so it only occupies the index position of 2048. If we use the address operator &) for the I variable, it returns to the position where the index is 2048. If this variable is of another type, such as int, it occupies 4 bytes and occupies the index 2048-2051 position in the array. The address operator returns the index 2048 position, because the int type starts at the 2048 position even if it occupies 4 bytes. Let's look at an example:

 
 
  1. // intialize a char variable, print its address and the next address  
  2. char charvar = '\0';  
  3. printf("address of charvar = %p\n", (void *)(&charvar));  
  4. printf("address of charvar - 1 = %p\n", (void *)(&charvar - 1));  
  5. printf("address of charvar + 1 = %p\n", (void *)(&charvar + 1));  
  6.    
  7. // intialize an int variable, print its address and the next address  
  8. int intvar = 1;  
  9. printf("address of intvar = %p\n", (void *)(&intvar));  
  10. printf("address of intvar - 1 = %p\n", (void *)(&intvar - 1));  
  11. printf("address of intvar + 1 = %p\n", (void *)(&intvar + 1));  

Run the command to get the following output:

 
 
  1. address of charvar = 0x7fff9575c05f 
  2. address of charvar - 1 = 0x7fff9575c05e 
  3. address of charvar + 1 = 0x7fff9575c060 
  4. address of intvar = 0x7fff9575c058 
  5. address of intvar - 1 = 0x7fff9575c054 
  6. address of intvar + 1 = 0x7fff9575c05c 

In line 1-5 of the first example, we declare a character variable, print the output address of the character, and then print the two addresses located before and after the variable in memory. We use the & operator and + 1 or-1 to get the first and second addresses. In the second example of lines 7-11, we did something similar. Apart from declaring an int variable, we printed out its address and the address next to it.

In the output, we can see that the address is in hexadecimal format. Note that the character address is 1 byte different from the character address. The int-type variable address differs by four bytes. The memory address algorithm and pointer algorithm are based on the size of the referenced type. The size of a given type depends on the platform. In this example, char is 1 byte and int Is 4 byte. Set the character address-1 to the address before the change, and the int address-1 to the first four addresses.

In this example, we use the address operator to obtain the address of the variable, which is the same effect as using a pointer to represent the variable address.

An illegal address for Storage & charvar-1 because it is located before the array) is technically not specifically pointed out. The C standard has been declared, and an Invalid Address stored on some platforms will cause errors.

Array address

In C language, arrays are adjacent memory areas, which store a large number of int, long, * char values of the same data type ). Many programmers use arrays as pointers when they use C for the first time. That's wrong. A pointer stores a simple memory address, and an array is a continuous memory area that stores multiple values.

 
 
  1. // initialize an array of ints 
  2. int numbers[5] = {1,2,3,4,5}; 
  3. int i = 0; 
  4.   
  5. // print the address of the array variable 
  6. printf("numbers = %p\n", numbers); 
  7.   
  8. // print addresses of each array index 
  9. do { 
  10.     printf("numbers[%u] = %p\n", i, (void *)(&numbers[i])); 
  11.     i++; 
  12. } while(i < 5); 
  13.   
  14. // print the size of the array 
  15. printf("sizeof(numbers) = %lu\n", sizeof(numbers)); 

Run the command to get the following output:

 
 
  1. numbers = 0x7fff0815c0e0 
  2. numbers[0] = 0x7fff0815c0e0 
  3. numbers[1] = 0x7fff0815c0e4 
  4. numbers[2] = 0x7fff0815c0e8 
  5. numbers[3] = 0x7fff0815c0ec 
  6. numbers[4] = 0x7fff0815c0f0 
  7. sizeof(numbers) = 20 

In this example, an array containing five int elements is initialized, and the address of the array is printed. Note that the address operator is not used &. This is because the array variable already represents the address of the first element of the array. The address of the array is the same as the address of the first element of the array. Then we traverse this array and print the memory address of each element. In our computer, int Is four bytes, And the Array Memory is continuous. Therefore, there is a difference of 4 between the addresses of each int element.

In the last row, the size of the array is printed. The size of the array is equal to the number of sizeof (type) multiplied by the number of array elements. The array here has five int variables, each occupying 4 bytes, so the entire array size is 20 bytes.

Struct address

In C, the struct is generally a continuous memory area, but it is not necessarily an absolute continuous area. Similar to arrays, they can store multiple data types, but different from arrays, they can store different data types.

 
 
  1. struct measure { 
  2.   char category; 
  3.   int width; 
  4.   int height; 
  5. }; 
  6.   
  7. // declare and populate the struct 
  8. struct measure ball; 
  9. ball.category = 'C'; 
  10. ball.width = 5; 
  11. ball.height = 3; 
  12.   
  13. // print the addresses of the struct and its members 
  14. printf("address of ball = %p\n", (void *)(&ball)); 
  15. printf("address of ball.category = %p\n", (void *)(&ball.category)); 
  16. printf("address of ball.width = %p\n", (void *)(&ball.width)); 
  17. printf("address of ball.height = %p\n", (void *)(&ball.height)); 
  18.   
  19. // print the size of the struct 
  20. printf("sizeof(ball) = %lu\n", sizeof(ball)); 

The output result after running is as follows:

 
 
  1. address of ball = 0x7fffd1510060 
  2. address of ball.category = 0x7fffd1510060 
  3. address of ball.width = 0x7fffd1510064 
  4. address of ball.height = 0x7fffd1510068 
  5. sizeof(ball) = 12 

In this example, we define a struct measure and declare an instance ball of this struct. we assign a value to its width, height, and category members, and then print the ball address. Similar to an array, a struct also represents the address of its first element. Then the address of each member is printed. Category is the first member with the same address as ball. Width is followed by height, which has a higher address than category.

You may think that because category is a character, and the variable type occupies 1 byte, the width address should be 1 byte higher than the start. This is incorrect from the output. According to C99 standard § 6. 7.2.1), it is boundary alignment. struct can add padding bytes to members. It does not record data members, but adds additional bytes. In practice, most compilers make each member of the struct have the same size as the largest member of the struct,

In our example, we can see that char actually occupies 4 bytes, and the entire struct occupies 12 bytes. What happened?

1. the struct variable points to the address of the first element of struct.

2. Do not assume that struct members are a large number of special bytes separated from other regions. They may have boundary bytes or the memory is not consecutive. Use the address operator & to obtain the Member Address

3. Use sizeof (struct instance) to obtain the total size of struct. You do not have to assume that it is the total size of each member domain. It may be supplemented.

Conclusion

This blog post helps you understand how to operate on different data types in C. In future blog posts, we will continue to study the basics of pointers and arrays.

Http://blog.jobbole.com/44845/.

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.