A detailed introduction to the basic pointer of C ++ (2)

Source: Internet
Author: User

This article is the continuation of the previous article.C ++InPointer.

Allocate memory on the heap

As mentioned above, the so-called heap allocation is to apply for memory from the operating system during runtime, but to apply for memory from the operating system, different operating systems provide different interfaces, there are different ways to apply for memory, which are mainly manifested by different function prototypes to be called. C ++ is a language and should not be related to the operating system. Therefore, C ++ provides a unified memory application interface, that is, the new operator. As follows:

 
 
  1. unsigned long *pA = new unsigned long;   
  2. *pA = 10;  
  3. unsigned long *pB = new unsigned long[ *pA ]; 

The above two pieces of memory are applied. The memory referred to by pA is the memory corresponding to the pA value) is 4 bytes, and the memory referred to by pB is 4*10 = 40 bytes. It should be noted that because new is an operator, its structure is new <type Name> [<integer number>]. it returns a number of pointer types. The <type Name> parameter specifies the pointer type, and the square brackets are used to specify the number of elements, the same as when defining an array, but it does not return the array type, but the pointer type.

It should be noted that the new operator above applies for memory from the operating system, instead of allocating memory, that is, it may fail. When memory is insufficient or for other reasons, new may return pointer-type numbers with a value of 0 to indicate memory allocation failure. Check whether the memory is allocated successfully.

 
 
  1. Unsigned long * pA = new unsigned long [10000];
  2. If! PA )? // Memory failure! Do the corresponding work

The above if statement is a judgment statement, which will be introduced in the next article. If pA is 0, then! The inverse of the pA logic is non-zero, so the logic is true, and then the corresponding work is executed.

As long as the memory is allocated, the memory needs to be released. This is not necessary, but as a programmer, it is a good habit of limited resources ). To release the memory, use the delete operator as follows:

 
 
  1. delete pA;   
  2. delete[] pB; 

Note that the delete operator does not return any number, but it is still called an operator. It seems that it should be called a statement more appropriate, but to meet its needs, it is still an operator, C ++ provides a special numeric type-void. it indicates none, that is, nothing. Therefore, the delete operation returns a number, but the returned number type is void.

Note that the release of pA is different from that of pB, because pA is returned by new unsigned long according to the initial writing, while pB is returned by new unsigned long [* pA. Therefore, when releasing pB, you need to add "[]" to the end of the delete statement to indicate that an array is released. However, in VC, both the former and the latter can release the memory correctly, there is no need for [] intervention to help the compiler correctly release the memory, because the VC of the program developed on Windows is allocated by means of the Windows operating system, when the Windows operating system releases the memory, it does not need to know the length of the memory block to be released because it has been recorded internally, actually, the C Runtime Library does these tasks, but it depends on the operating system, that is, there are actually two layers of memory management packaging, which is not shown here ).

Type modifier type-specifier)

A type modifier is a type modifier. It is used to further specify how to operate the memory corresponding to a variable when defining a variable. Some common operation methods, that is, this operation method applies to each type, so they are separated separately to facilitate code writing, just like fruit. Eat the apple flesh, eat the Pear flesh, do not eat the apple skin, do not eat the pear skin. Here, Apple and pear are both fruit types, which are equivalent to the type, and "XXX flesh" and "XXX skin" are used to modify the type of Apple or pear, to generate a new type-Apple's flesh, pear skin, which is equivalent to a type modifier.

The array and pointer mentioned in this article are both type modifiers. The "&" referenced variable previously mentioned is also a type modifier.

The Type modifier only works when defining variables, as shown in the previous

 
 
  1. unsigned long a, b[10], *pA = &a, &rA = a; 

The above three types of modifiers are used: "[]", "*", and "&". The above unsigned long is now called the original type, indicating that the previous type is not modified by the Type modifier. The following describes the functions of the three types of modifiers.

Array modifier "[]" -- it is always followed by the variable name, and an integer c is placed in the brackets to specify the number of array elements, it indicates that the current type is stored continuously for the original type of c elements, and the length is the length of the original type multiplied by c. therefore, long a [10]; indicates that the type is continuously stored with 10 long elements. The length is 10*4 = 40 bytes. Long a [10] [4]; indicates that a is continuously stored with four long [10] elements. The length is 4*40 = 160 bytes.

I believe it has been found that because multiple "[]" can be connected, there is a relationship between the computing order. Why is it not that 10 long [4] elements are stored consecutively but are reversed? The Type modifier is calculated from left to right. Therefore, short * a [10]; indicates continuous storage of 10 elements of the short * type, with a length of 10*4 = 40 bytes.

Pointer modifier "*" -- it always comes before the variable name, indicating that the current type is the original type pointer. Therefore:

 
 
  1. short a = 10, *pA = &a, **ppA = &pA; 

Note that the ppA here is called a multi-level pointer, that is, the pointer of its type short, that is, short **. short ** ppA = & pA; calculates the address value of pA. A number of short * type is obtained, then, the "&" operator converts the number to the pointer type number of short *, and finally assigns the value to the variable ppA.
If the above is dizzy and you don't have to think about it, you just need to pay attention to the type Matching. Below is a brief description: If the address of a is 2000, the address of pA is 2002, the ppA address is 2006.

For

 
 
  1. pA = &a; 

Calculate the value of "& a" first. Because a is equivalent to an address, "&" is used to convert the number of a's address to the long * type and return the value, then assign the value to pA, and the value of pA is 2000.

For

 
 
  1. ppA = &pA; 

Calculate the value of "& pA" first. Because pA is equivalent to the address, "&" plays a role, directly convert the number of pA addresses to the long ** type because pA is already of the long * type), return the value, and assign the value to the ppA. Then, the ppA value is 2002.

Reference modifier "&" -- it is always connected to the variable name, indicating that the variable does not need to be allocated memory to be bound to it, but cannot be included in the description of the type, which is described below. Because the corresponding variables do not need to be allocated memory to generate ing, they are not similar to the above two types of modifiers and can be repeatedly written because it is meaningless. And it must be on the right of the "*" modifier, that is, it can

 
 
  1. long **&a = ppA; 

But not

 
 
  1. Long * & *;
  2. Or
  3. Long & **;

Because long * & * indicates the reference pointer of the long pointer in the order calculated by the modifier from left to right. The reference only tells the compiler not to allocate memory to the variable on the stack, actually, it is irrelevant to the type, so the referenced pointer is meaningless.

Long & ** indicates the pointer of the referenced long pointer. Similarly

 
 
  1. Long & a [40]; // incorrect

Because it indicates allocating a memory of 40 elements that can be continuously stored as long references, the reference is only a means to inform the compiler of some type-independent information, it cannot be instantiated as a type.

It should be noted that the reference is not a type, but for convenience, the reference of long is often referred to as a type), and

 
 
  1. Long ** & rppA = & pA; is incorrect

The preceding statement does not allocate memory to the variable rppA. The address after "=" is directly used as the corresponding address, and & pA does not return an address-type number, it is a pointer type, so the compiler will report a Type Mismatch Error.

But even if

 
 
  1. long **&rppA = pA; 

It also fails, because long * and long ** are different, but the following is acceptable due to the type Matching:

 
 
  1. long a = 10, *pA = &a, **ppA = &pA, *&rpA1 = *ppA, *&rpA2 = * ppA + 1 ); 

The Type modifier and the original type are combined to form a new type, such as long * & and short * [34, note that the <type Name> in the new operator requires that the type name be written, you can also write the preceding long *, that is:

 
 
  1. long **ppA = new long*[45]; 

That is, a 4*45 = 180 bytes of continuous memory space is dynamically allocated, and the first address is returned to the ppA. Similarly, you can:

 
 
  1. Long *** pppA = new long *** [2];
  2. While
  3. Long ** pA) [10] = new long * [20] [10];

It may seem strange that the type of pA is long **) [10], which indicates a pointer to an array with 10 long * elements, the allocated memory length is 4*10) * 20 = 800 bytes. Because the array modifier "[]" can only be placed behind the variable name, And the type modifier is always calculated from left to right, the pointer to an array of 10 long elements cannot be used, because "*" on the left side is always better than "[]" on the right side.

Therefore, C ++ proposed the above syntax to enclose the variable name in parentheses to indicate the final Modification of the type in it,

Therefore:

 
 
  1. Long * a) [10];
  2. Equivalent
  3. Long * a [10];

While

 
 
  1. long *&aa)[10] = a; 

Otherwise, use

 
 
  1. long *&aa[10] = a; 

The cause is described above ). While

 
 
  1. long **pA)[10] = &a; 

It can normally represent the type we need. Therefore, you can

 
 
  1. Long ** & rpA) [10] = pA;
  2. And
  3. Long *** ppA) [10] = & pA;

I hope that through the introduction in this article, you can clearly understand the pointer concept and usage in C ++.

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.